React Native: my native developer first impressions
About 8 weeks ago, I embarked on a new project. A brand new mobile app to be coded in React Native. I was excited to learn a new technology and my client (a French startup) was excited at the prospect of getting their first mobile app off the ground. Once the project is live in the stores, I’ll make sure to add a link to the app.
To give you some context I’m an iOS developer who has created native apps in the past. I’ve lead a team to create a fairly large iOS app and consider myself to be a senior/lead iOS developer who puts a lot of emphasis on software quality and shipping high-quality software.
Here is what I’m taking away now that I’m done.
The tooling is hard to get right
Here are the tools that made my life easier
- VS code: I started by using Atom and on a friend recommendation, I switched to Visual Studio Code. This was a good choice, though I still miss Xcode. I like the integrated nature of Xcode. Right now, I have to use three or 4 different tools to edit my code and debug my code.
- VS code setting: a package that will set up VS Code in a way that works for React Native. Now that I have worked with this configuration for a few months, I’d probably remove a few things. But that made my life a lot easier to start. https://www.npmjs.com/package/react-native-vscode-settings
- Storybook: when people ask me what my perspective is on React Native, this is one of the tools I always mention. This specific tool does not exist for native development. In React Native everyone always stress that it is super fast to see your progress: no compilation required. While it’s true, they forget to mention that applications are made of a lot of screens and to see certain screens, you have to navigate between screens. This navigation can be really tedious sometimes. This tool will make it easy to make sure the screen you work on is always the first one you see. Making updating your UI a lot easier.
- Read the documentation on how to upgrade React Native, there is a tool to do it simply.
Getting a consistent environment across machine is a pain
I have a development machine for when I work from home and a secondary machine for when I’m on the go. Keeping those two in sync has proved a pain with time wasted when I transitioned to the “on the go” machine which I use once a week (non-matching react native versions, different plugin in VS code). I have not found the perfect solution yet and I’m playing with gitHook script to help make sure things happen as needed when I pull code from git.
I also don’t waste as much time as I used to as I’m better understanding the eco-system and know how to solve basic issues now.
I have started using code setting sync plugin to help with this but this has not solved all the issues.
No UI editor
React Native uses JSX as the language to represent the UI. It actually works fairly well. Except when you come back to a screen you created 3 weeks ago and you’re trying to figure how you structured things.
I found the hard way that comment is JSX is a bad idea (works great on iOS, crash on android), so you’re left with a block of 50 to 100 lines with no comments to help you structure your code.
There has been a couple of effort to create a UI editor (Deco which is more or less abandoned by the original team) and another one which I can’t remember the name of.
The essential flow I have seen in those tools is that they are still heavily relying too heavily on the JSX. The JSX is constantly displayed, you can tweak a few parameters in the UI and the view is reloaded in the simulator. You are not directly manipulating the UI, doing the layout is not really practical in those tools.
If this is something you find annoying too, please reach out (Olivier Destrebecq). I’m building a prototype right now to fill that void.
/* TODO: $FlowFixMe */
a few times in the project because I could not figure it out and I could not spend more time on that rabbit hole. This will sometimes save you a lot of time at the expense of code quality.
There are tons of third party components of varying quality
Also, make sure that the cost of you learning that specific component is not higher than the cost of you implementing the control and learning a lot on the way. For example, in the project I had to implement a bar graph. I tried to use one of the main graphing libraries which took me time to figure out how to use, only to find they did not support rounded corner. I ended up rolling my own in less time it took me to figure out the first library… (which I ended up using for a stacked bar graph so all was not lost :-)
The performance was great, until I started drawing my graph and putting then in FlatLists. Then all hell broke loose.
Debugging performance issues is never fun, though I have learned to enjoy it when doing native development. Using Instruments to find bottle necks is always fun and the task of finding how to do it in a more performant way is even more fun.
The same tasks on React Native seemed more tedious and relied heavily on …
:-(. In the doc, it is mentioned that Instruments is also an invaluable tool, but to be honest I could not figure it out. Maybe on my next project :-)
In the end I got to learn about the method
and the whole state mechanism used by React Native. Good stuff to know. The only question I still have lingering in my mind is whether I would have had to spend as much time on performance issues if I had done this natively. My gut feeling is no, but I could be wrong.
The thing to remember with React Native is that you don’t get to use threads. So everything is single threaded. That has not been too much of an issue for me as I did not have long running tasks, but that could be an issue for you.
Debugging in chrome is okay, that’s it
Being used to Xcode, debugging in Chrome is an okay experience. Every time I reload the app in the simulator, chrome debugger reloads. Meaning you might very well loose where you were in your code, break points works right 95% of the time. For some unknown reason for about 5% of the cases I ran into issues which forced me to take extra action to debug my app. I ended up using
way more than I would I usually do.
When you’re debugging layout don't forget to check react-devtools, it will give you a lot more details than the chrome debugger will give you. I also have not dove into the advanced tools offered by chrome for performance debugging
Higher Order Component is a must
Known as HOCs, they are invaluable. One thing to know about React Native is that subclassing is a big No No. So what are you left with? Composition. You take a component and you wrap it in another component that adds the desired behavior. This will feel weird at the beginning, but you get used to it fairly quickly. Then you discover that you want to share behavior across mulitple components and you look for a way to do this and this is when you run into HOCs. I highly recommend reading this page as it helps you get going. Also, read this page about how to type them using Flow… No way I would have figured it on my own…
The closest thing I would equate them to are concrete protocols in the iOS world. It allows you to add common behavior to your component without subclassing.
Some of the tools which are very mature in native development are still a little young in React Native
Get more RAM for your development machine
I used to be able to get by with my 8Gb of RAM on my main development machine. But the android emulator and chrome debugger did not appreciate this. I’m now at 24Gb and am not running into issues anymore.
Get ready to learn
Redux and friends
I stayed away from Redux for this app as after reading their doc page as to why You might not need Redux. I’m planning to use it (or something similar in my next projects), but to be honest, everything I read is that is adds a layer of complexity you can sometimes do without.