Software Engineering

Going mobile with React Native

Clubhouse

Illustration by Michele Rosenthal

When our friends at Wayup heard that we were working on a Clubhouse 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 Clubhouse 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 Clubhouse, 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 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:

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!