When I started working with React Native around January 2019, I had a good understanding of how the React worked in the HTML browser context. Since I was familiar with React patterns, I thought I might have an easier time getting started with React Native development. I felt like that was true, but I wanted to share a few things I ran into while getting started.
The in-app inspector in React Native is significantly harder to move around than the one for React Web.
You can use react-devtools to get a somewhat more workable tooling that works like the React browser extension, but it's not feature-complete either. You'll still need to debug with Safari for iOS sometimes and wrangle with the weird WiFi/host/port settings to switch between debugging in a simulator and a real device.
The React virtual DOM tree is going to have a lot more noise (see example), since many library (or even core) components are made up of other components. You'll see all the abstractions in the tree.
Rather than HTML browser elements, React Native has its own set of base components that you'll build layouts with.
On the surface they seem like equivalents, it's not really helpful to say "this HTML component is this in React Native" since you can't rely on them having the same behavior. To illustrate how this falls apart quickly:
Although a little time-consuming, I recommend spending some time playing with the base React Native components. It's helpful in building a new mental model for layouts in React Native.
Also, a lot of common mobile application UI/UX patterns are available out-of-the-box like ActivityIndicator, so you can spend your time building features and not recreating native mobile experiences.
Display types are flex or none. There's no inline, so get used to Flexbox properties.
The default flexDirection is column and not row.
Some properties that would "pass through", as you would expect to be able to do in the browser, doesn't in React Native.
An example is the inability to style children text color in a parent View.
Also to be accurate, these are not CSS but "Layout" properties in React Native. Many properties have familiar names with similar behavior, but you'll come across new ones like paddingVertical or aspectRatio.
The native modules abstraction is not very friendly, so expect to spend more time on it when you really need to implement your own bindings.
This isn't because your project will break overnight, but because eventually you will want to upgrade.
I found that upgrading React Native skipping several versions is sometimes a very painful exercise with a lot of fuzzing with native code. It's hard to track down what is breaking and what needs updating. If you're using Expo, you likely won't need to directly upgrade React Native, but it doesn't hurt to bump the versions of your Expo dependencies when you can, for the same reason.
React Native has a tool to help with upgrading, but it is a fairly manual process. You'll need to sift through all the diffs, determine what parts are project-specific, old React Native boilerplate, or new React Native boilerplate, and mash the project-specific and new boilerplate parts together.
React Native has its quirks, and even with prior React experience it still has a somewhat substantial learning curve. However, I actually found developing in React Native a pleasant experience overall, dare I say fun.
Expo is definitely the way to go if you're just looking to get things done, especially if you don't need to do anything fancy and device specific. With it, you're likely to get CRUD operations working on-device within a few days.
Give it a shot!
June 13, 2021
Are the articles up-to-date or still relevant? Explainer here →