Our Journey Building a React Native App
Then an existing client of ours, one that’s been having month on month growth from an existing Mobile-friendly website we built for them, approached us with a new request: An App on both iOS and Android, capable of covering some of the offline features not currently possible on the Web.
Then we had an idea – what if we could leverage our existing talent in house to produce this App? That way the client wouldn’t need to work with 2 agencies and we’d get to learn how to produce software for 2 entirely new platforms!
So we started looking into the skill-sets sets required to pull this off:
- Design – we would need visuals and UX decisions before anything can begin. Something we already have in house.
- API development – App’s tend to be primarily API-drive and we’re a Magento agency – working with data & APIs is our bread and butter.
- Finally, App Development. This would would involve either: 1. hiring Swift and Java developers to create the twice, once for each respective platform, or 2. utilise our existing Frontend developers if possible.
It’s so funny, because it’s so true. Enter React Native, from Facebook.
There are other solutions out there than achieve similar results, but some of the reasons for choosing React Native were as follows:
- It’s actively developed by Facebook – there’s a release every month!
- 90% of the code is shared across the iOS and Android platform – there are just a handful of situations in which a platform-specific components are needed.
- It’s not just a web view wrapper – React Native gives higher performance & tighter integration with the host platform than other tools.
React Native is not for beginners.
Around the JH offices, you can often hear me repeating a phrase that I once heard from some other, much wiser developer:
don’t ever get married to a particular library or framework, or even programming style – instead become an expert at the underlying language
Because we follow this idea, the fact that iOS and Android were completely alien platforms to us wasn’t too much of a hurdle – we just needed to learn the ropes in React Native. So we dived in.
How we did it.
Along with React native, the following handful of tools were some of the most important we used to create the App.
Having the entire applications state within a single immutable store enabled us to impose a restriction on state updates that occur throughout the App – it’s a strict pattern of “UI raises an event -> reducers return a new state -> components re-render with that new state”. Also with Redux being so popular, there tends to be a middleware for each problem you encounter (such as persistence, logging etc) and the dev-tools experience makes debugging a breeze.
Via redux-observable, we were able to move all of the side-effecting behaviours from components and instead place them at the edges of the application, into what are known as
epics. These are just plain functions, but they exist outside of the lifecycle of any components and can observe all actions that pass through the store. This makes them perfect for the composition of async behaviours – and we use them heavily to power everything from Network requests, to Alert windows and Camera management – basically anything that does not fall under the React API, we wrap in Observables and compose at will. Handling all of the side-effects inside epics, rather than in components, allowed us to more gracefully handle errors and to retry or recover where possible – something that can get really tricky in raw React.
Flow allowed us to add these types in an incremental way, via the
We’re big users of Flow’s rival Typescript here at JH, but were impressed with how far Flow has come along given it’s relative immaturity compared to Typescript.
Now that the App is live, and we’re well under way with new features and phases of work, we can look back and reflect on some the biggest lessons we learned during the process:
- Choose tools that make debugging easier. Redux, Redux dev-tools and other tools like these come into their own when your application goes wrong. There cannot be enough said about choosing tools that will help you in the bad times.
- Use tools to automate the linting and auto-fixing of your code (where possible). Conversations about code style & syntax are a waste of everyones time, just set up some rules, and have everyone follow them. Even better, have your builds fail when they do not!
- Write tests at as high a level as possible – if you can write just one test capable of exercising 5 function calls, and you can still assert on the inputs/outputs, then do it. Don’t aim for 100% coverage.
- Get a grip on side effects, move your interactions with the outside world to the edges of your application.
- Don’t put off adding error handling, it will always come back to bite you. Utilising libraries such as redux-observable can help greatly with this.
We were faced with a tough decision – 1) outsource work because it involved deploying to a platform we had no experience with, or 2) dive in head first and use our expertise in design and development to deliver what the client wanted.
We relished the challenge, drawing upon multiple areas of the team and ended up producing something we were all extremely proud of.