Wait one second! Aren’t you the guy who wrote “Five Reasons Your Team Should Use React Native”?

Yes, yes I am.

I really do enjoy React Native, as my previous article states. There’s a lot of reasons to use it, but just because I advocate RN, doesn’t mean some things don’t suck. Just like any relationship, you have to be in it to really understand. Trust me, it’s not all rainbows and unicorns. Here’s what hurts:

React Limbo

Most of the time, I hit run in Xcode and I instantly minimize it. I’m usually good for the whole day. Every so often (about once a week for a full time dev team), something goes to hell. I don’t mean, just restart packager kind of hell. I mean, I just merged a branch from another dev, and now things are crazy wrong kind of hell. Usually, you can fix this with the following:

close node packager

stop chrome debugging

rm -rf node_modules in terminal

in terminal Command + Shift + K in Xcode

in Xcode reset simulator

npm install in terminal

in terminal run everything again

This is worthy of an npm script since it’s what we do on every upgrade. I’ll break down and make it soon enough. BUT! on occasion, this won’t work. No clue how to reproduce or what part is the culprit, but this usually happens when switching computers and branches. Something is still cached.

UPDATE!

Looks like others have finally solved this: https://github.com/facebook/react-native/issues/4968

Be sure to also run: watchman watch-del-all and npm cache clean

UPDATE!

The takeaway: I’ve gone so far as logging out and back in — which does fix this.

Upgrades

First things first. When I look at something like lodash docs, there’s a filter at the top left that helps me identify what version has what docs. This is not so with React Native.

UPDATE!

THEY DID IT

UPDATE!

You can read the docs, implement a feature, and then … nothing. *Sad Trumpet* — Once something’s documented on Github in a release candidate, it’s on the main docs site, and there’s nothing but git blame to help you see that the docs were for something unreleased. This bites me all the time, considering how fast RN is evolving. Fortunately, the release candidate gets shipped pretty quickly thereafter, but that leads me to the next issue….

The Trap

Look at this new shiny model that was just released! It’s got a (insert Willy Wonka word here). Oh, but it’s in the newest version of React Native, and you’re one version behind. Just go ahead and do a simple upgrade, and then get back to work!

INSTANT DEATH

Hahaha, ok, necromancy notwithstanding; upgrades are not always straightforward. Depending on how fundamental the changes were, your existing application may have to change fundamentally. Some upgrades take 5 minutes, some take the whole day.

Even though your updates can be done by one person, and then shared by all for that project, if you’re upgrading multiple projects, it’s a good idea to document your upgrade path for all other projects.

The takeaway: don’t assign a small amount of time for upgrades for React Native versions.

Fight of the Navigator

By a landslide, the cross-platform navigator has been the most magnificent, and the worst experience of React Native.

I could write an entire blog post on the battles waged to wield the React Native cross-platform navigator. But then you’d say, “Gant, this blog post isn’t a pity party! It’s the most amazing informative post I’ve read in a while, so don’t screw it up.” Wise words, wise words. And you’re right, so let’s jump in.

Q: Why is it that so many people are releasing their own navigation+routing modules?

A: Because the provided navigation isn’t something you immediately feel at home using.

I love the Navigator, because I’m not locked down to Native. I hate it, because it feels like reinventing the wheel.

Docs Again

I spent a lot of time reading code to help me understand the docs. That’s usually a red flag. The short example in the docs is enough rope to hang yourself.

Navigator State

Since the navigator is shared across screens, changes to the navigator’s state are also shared across screens. EEEP, that’s kinda hard to swallow. In my mind, each screen/scene should manage the title and buttons shown in the navigator (ergo the navigator state). Sure, routes can chime in, but the real and final say is each screen, so you can dynamically add and remove components from the navigation.

Through a LOT of wiring and bending, I’ve somewhat got this working with one major exception. I can’t reference the current scene/screen from the Navigator. Lord Binary knows if that’s simple or impossible, but I can’t find it. So if I pop my navigation stack, I can’t ask my currently focused screen to run code that pertains to that screen.

I shouldn’t have to! It feels dirty. I want a navigator I can configure.

Button Mashing

If someone smashes a button 100 times which runs navigator.pop(), you’ll pop with animation, over and over and over. This can get you in corners and nav states you never expected to be in. Same goes for navigator.push(). As far as I know, there’s no easy way to stop this, unless you implement debounce in every navigation function. I really would like a centralized way to enforce disabling navigation instruction during transition state.

Fortunately

I’ve heard rumors that there is an updated RN Navigator on the way. What will be solved? We’ll have to try it and see.

The takeaway: spend a lot of time getting comfortable, and stretching the limits of your Navigator code earlier rather than later.

Switching from Sim to Device

This one is probably just me. While developing, all that speedy magic comes from a node server; a node server you have to have network access to. That means your code’s default `localhost` isn’t going to cut it on the device.

Yes, you can simply edit it to your local IP every-time you want to test on a device.

Yes, you could write a script that checks the build target, and attempts to sub your IP, like Steve Kellock does.

I’m not happy with either of those solutions, and React Native is working on it. In the meantime, I’m using Exponent to test on my device, which takes advantage of ngrok. It’s kind-of a duct tape solution for something that’s so simple, but I take it.

UPDATE!

This too is fixed! You can now deploy to device, and it will find your IP via quick xp.io. It will even bundle for production without any preprocessor directives! Works like a charm!

UPDATE!

The takeaway: building for your phone requires a small code change (for now). Exponent helps you test on multiple devices local and remote.

Conclusion

I don’t think I’ve unearthed any game-changers, but it does show the topology of where React Native is and its growing pains. This is must-have knowledge for anyone jumping into React Native. Overall, I’ve been involved in tool-chains for cross platform development for a while, and I have to say, the velocity for React Native looks solid.

About Gant

Gant is Technical Lead at Infinite Red, published author, public speaker, and mad-scientist in training. If you’re looking to discuss nerdy tech, he’s all ears. View half-witty half-groan technical tweets with @GantLaborde on twitter.

Takeaway image provided by: http://www.freeimages.com/photo/chinese-take-away-box-1319752