Going mobile with React Native
When our friends at Wayup heard that we were working on a Shortcut mobile app using React Native, they were eager to hear more about our experience and whether we had any tips or recommendations. So our mobile developer, Eli Perkins, and I headed up to their office for a “lunch and learn” session on React Native and what we’ve learned in the process of building and alpha testing the Shortcut iOS app.
Here’s a few key takeaways and a sneak peek or two at where we are headed.
If JavaScript is Your Jam, React Native Might Be Too
Here at Shortcut, we have a lot of developers who are extremely proficient in JavaScript and no other mobile developers.
Coding our mobile application in ReactNative meant that Eli could easily work within our established pairing and code review regime. It also helped us avoid adding too much mystery to our codebase.
A UIView written in Swift
The same UIview written in React Native + JSX
It Is Just ReactJS + Native Views
React Native uses standard React concepts like render model and UI as a function of state and properties but it is not a webapp. When you build your application in React Native, you are still running native code in an native app using a native framework. The Javascript framework is just handling the business logic.
For example, you can use GraphQL with React Native and also try out bleeding edge tools like Bucklescript (edit 2022: renamed to ReScript) while also availing yourself of anything iOS or Android have to offer.
React Native allows you the best of both worlds.
Learn Once, Write Everywhere
Some people are operating against the false assumption that React Native enables developers to write an application once and deploy it across all platforms, but that unfortunately is not the case.
It is not a silver bullet and it wasn’t meant to be. The beauty of React Native is that once you grasp the concepts, they can be applied across many platforms.
However, the “native” aspect of React Native means that you want to be sensible about what works best for which platform and avail yourself of the native tools to give the user the best experience for their device and OS. According to Eli, “The user experience is better if you drop into native.”
Consider Abstraction and Composition
When building with React Native — just like with any large task — you want to take the time to think about your use case. You must establish what you want to accomplish and explore your options for getting there. Eli suggested that you ask yourself, “What are the right abstractions, the right separations of concerns?”
For example, you can hardcode how to access the data into the component that’s rendering the view, but that might require you to duplicate the same work in every new component that wants to access that same data store.
Using a tool like the Redux container, you have the option to create a handy layer of abstraction between your component and your data store and give yourself (and your app!) some flexibility.
While Redux is what we use, it isn’t your only option for abstracting from how to fetch data. You can also try Realm or React Native’s Async Storage, and those who want to make a more gradual transition to React Native could even just pass data from the iOS Core Data store to a single React Native view.
It’s Not Without (Potential) Pitfalls
One of the main “gotchas” for us was threading. There is, as of yet, no multithreading story in React Native.
While there are workarounds like the Animated library in React Native, it doesn’t adequately address data processing requirements. If your application is churning through a large JSON blob, generating some state from your reducers, and acting accordingly, your other Redux actions will be stuck in the pipeline.
The threading impediment also made it clear that we needed to rely on native navigation rather than React Native. Any outside navigation library is always going to lag behind any changes made by Apple or the Android team, and the user experience will suffer. While there is some interesting navigation work being done by teams like AirBnB and Wix on this, we’ve decided to stick to what works for us.
Tool Tips
- Jest allows us to test a lot of Javascript logic, and it makes our build times super fast. While there are benefits to testing rendering of views on iOS we’ve found it more useful to write unit tests just for Javascript rather than checking on React Native bindings.
- Flow is static type checker that helps you avoid simple bugs, for example if you try to access a null value; identify type signature changes; smart autocomplete for code. According to Eli, “If you like having types from Swift, you will love having Flow. I can’t gush about it enough.”
- Prettier is a code formatter. “We have 100% time to talk about content of code, 0% on styling due to Prettier,” said Eli.
- We realized early on that using hot reloading meant that we didn’t have to recompile the app every time we made any change. Do it!
Do Your Homework
There are ample resources out there to learn and explore your options in React Native. Many teams including those primary maintainers at Facebook are using it and building useful libraries. Here are a few resources Eli recommends:
- Lessons by Kent C Dodds and Dan Abramov on Egghead.io
- AirBnB’s Painting With Code library
- Why Artsy moved to React Native
- Discord on Using React Native: One Year Later
- React Native in the "Brown Field" - AirBnB’s Leland Richardson at React Conf 2017
- React Native Documentation
Happy learning and building! Our own React Native mobile app is being polished and we fully expect to have the iOS version available to beta users in the coming months. If you are interested in being a member of the beta group, drop us a line!