At ZDEV, we’ve been working with React Native for about 18 months and built three apps. We wanted share some tips we learned along the way.

First let me start by saying we love React Native, we’ve written a blog post about why we think it’s a game changer for app development.

Improve layout consistency across different device sizes

Your mobile app will need to run on different sized devices, 5s to 6plus size and a host of different sizes on Android. You’ll notice when you build a screen that looks fantastic on an iPhone 6, it’ll look weird on the 6 plus.

We wrote a function which takes a style object and scales certain style properties up or down. Everything is relative to an iPhone 6 (iPhone 6 will never be scaled up or down). We experimented with which style properties should be scaled. In the general case it performs pretty well and if you build it for iPhone 6 it will look good on all other devices. You can check it out here.

Centralizing this code is important. We’ve seen projects with scaling hacks all over the code base, it makes sense to have a single strategy of how to do the scaling and then adjust it as you go.

Turn off packager caching

The packager supports caching which speeds up the first transform when you restart the packager. Caching is on by default, however, we grew to not trust for this functionality when things broke. In the end we turned it off, things are slower when you start it up, but the same speed after that.

It’s well worth it once you’ve wasted half an hour chasing your tail because you didn’t reset the cache properly.

//In your package.json scripts section "start": "node node_modules/react-native/local-cli/cli.js start --reset-cache"

The Navigator

The navigator component is one of the trickiest parts of building your average app with React Native. Over time we’ve refined a component which wraps Navigator that I think would work well for most apps.

Managing Routes

Components will often mention other components via routes. e.g. Component1 should props.navigator.push to Component2 . You can get into weird situations with cyclical dependencies.

For our project we have a single routes.js where all the components are lazily loaded. Our navigator component supports passing props and changing the transition animation.

The overhead of updating React Native versions

The team behind React Native release it at a frightening pace - every two weeks with massive list of features. This is fantastic! But it means after 3 months of development you’re 6 versions behind.

How to upgrade

Upgrading can be tricky, it depends on the particular release and luck. The strategy which has worked best for me is to upgrade one version at a time e.g. 0.39 -> 0.40

Update the React Native dependency’s version in package.json

npm install

Run react-native upgrade

Choose diff and manually integrate changes they’ve made

You can then restart your packager and test your app on Android and iOS. It’ll either work (the last 5 or 6 versions have been smooth for me), or break horribly.

If it breaks, upgrading just one version means you’ll have a narrower set of changes to consider when hunting down the fix.

Wrap the React Native components with your own

We use components a lot, often to wrap React Native’s components. Always want Text to have your font? Create a Text component where you pass all the props straight through but make a couple of modifications.

This is a core strength of React that you’ll want to use.

Split your Native code from your Javascript

If you’re deploying your Javascript using CodePush, having one code base for the objective C and Java code and a separate one for just your javascript this makes it easy to use git to check you don’t need to rerelease to the AppStore when you plan to release using CodePush.

Split your code into npm modules and use npm link

Splitting your code into separate modules is a good idea. One of the big advantages of React Native is you can create npm modules which can be shared between your app and your website.

We use Redux with our projects, we update Redux files regularly and your dev flow will suffer unless changes are visible in your app as you’re debugging. Normally you would use npm link - Unfortunately this doesn’t really work.

Our solution was to use rsync to manually copy the files into npm_modules which is pretty hacky but has worked very well.

React Native isn’t quite mature

It’s still a relatively new project, and the complexity it’s taking away from you is really quite amazing. There are bugs - Some of them have cost us significant time on projects.

The community and developers are excellent and bugs are getting fixed all the time.

I think in about a year a lot of React Native’s maturity issues will be behind it.

No SVG support

You can’t really require SVGs in a practical way (some third party libraries have tried). I had to write some scripts to convert my SVGs to .png s. I’m sure they’ll get to it.

Android

Developing with Android is not as polished as iOS. Things have improved drastically since I first used React Native with Android.

Layout isn’t consistent

So you’ve written your shiny new component and made it pixel perfect on iOS. You double check it on Android and it looks different. This happens to me pretty regularly, it seems to happen more often when a Text component is involved. I then end up with ternaries in my styles to fix it.

The inspector doesn’t work properly

On iOS it works perfectly. On Android clicking on an element often won’t select it. So you’re forced to solve your layout problems blind.

Debugging doesn’t really work

It sort of does, but your app will run so slow it’s unproductive to the point where it’s not worth it.

Performance issues

Minor performance issues on iOS made the app unusable on Android. The biggest one was logging to the console. Turning this off made my app much faster.

console.log = () => {} // Don't log anything!

We hope some of these tips will be useful. We certainly wish we’d known them when we got started. As always I’m contactable at richard@z-dev.io or in the comments :)