skip to content
Andrei Calazans

Keeping up with React Native

/ 7 min read

Inspired by https://maxrozen.com/keeping-up-with-react-libraries/

Warning - Highly opinionated material 😂

This post is organic, I will continue to update it with relevant stuff related to React Native.

See history of changes

Table of Contents

Accessibility

Basically you need to know:

  • accessible
  • accessibilityLabel
  • accessibilityRole
  • accessibilityHint
  • and the Module: AccessibilityInfo

See official documentation on accessibility.

Also, use FormidableLabs’ ESLINT plugin to ensure accessible components

Animation

You can use the Animated API with useNativeDriver: true for most simple animations. But, for more complex animations that are driven by user interaction like swipes and scrolls make sure you are using something that uses reanimated under-the-hood.

  • react-native-redash Redash is a utility library powered by reanimated made by William Candillon, creator of [Can it be done in React Native?](https://www.youtube.com/user/wcandill) series.

  • react-native-reanimated And reanimated itself. Version 2 of this library is a complete rewrite making it way more developer friendly, previous version had a steep curving learn.

Companies

Short list of impressive companies that are using React Native:

  • Shopify
  • Coinbase
  • Microsoft
  • MLS
  • Sky UK | NowTV
  • Tesla
  • MLS
  • Wix
  • A&E
  • Discord
  • CruncyRoll | Ellation
  • Peloton

There are posts, job listings, and public libraries that prove these companies are using React Native. Plus, I have personally worked as a contractor for some of them.

Component Libraries

Which one? Well that depends, I like react-native-elements because it doesn’t try to do too much, it is simple and lightweight. Native Base is famous for being vast and offering support for web too.

There are more UI libraries for React Native, but most serious products will develop their own system design and component library. Use react-native-elements as an inspiration.

React Navigation started off as the easiest way to do navigation on React Native, mostly because it was implemented fully in JavaScript and to use it you only needed to npm/yarn install.

React Native Navigation, on the contrary, implemented a fully native solution that required linking the native parts. Linking the native parts was not straight forward, thus many preferred React Navigation.

Nevertheless, navigation done fully in JavaScript has and had its drawbacks like performance and non-native look and feel.

For a cross-platform solution that includes the Web, react-navigation is the best approach.

For native performance plus look and feel, you can use either react-native-navigation or react-native-screens/native-stack.

New Navigation Module

Graham Mendick introduced another approach to navigation for React Native with similar principles of React Native Navigation. I wrote about it here (@TODO - Not yet public).

Native Modules

If you are going to implement a native module use the following library for help:

https://github.com/callstack/react-native-builder-bob

There is a page in the docs dedicated to this as well.

Supported Platforms

  • iOS
  • Android
  • Windows
  • OSX
  • Android TV
  • tvOS
  • Tizen
  • Roku
  • LG webOS
  • Fire TV
  • PS4
  • XBox

Relevant links:

For iOS, Android, and AndroidTV see https://reactnative.dev/

For Windows, XBox, and Macos see https://microsoft.github.io/react-native-windows/

For tvOS see https://github.com/react-native-tvos/react-native-tvos

For a more unified solution that has all 12 platforms see https://www.youi.tv/youi-engine/react-native/

Renative tries to target all handsets, tablets, and 10ft devices with a single build system. It is still early and it does not seem to have serious financial support, but it has shown some growth.

Performance

Performance is a broad subject. If you think you got a performance issue, first identify where/when?

On Initial App Load

Watch Parashuram N talk on React Native architecture to better understand where the problem might be. The initial load can be improved by reducing bundle size, RAM bundling, and lazily loading native modules.

On Initial Component Screen Loads

Step through code and double check you don’t have awaits holding the JavaScript thread from updating the main thread. Remember React Native batches events in the JS thread to send it off to the main thread, if your JS thread is awaiting a network reply, you are blocking the bridge from updating the UI/Main thread.

While Scrolling Lists

First see if you can just use a FlatList with the right optimization props, see this post.

If that’s not enough and you still struggle, checkout the RecyclerListView.

If your company still find it slow, implement a native view where the list is fully handled natively for both iOS and Android 😅.

When Navigating

There are multiple problems you can face here, like slowness with the animation or lack of responsiveness. If it is an animation issue check out the animation point below.

For unresponsiveness you can check where the navigation is being dispatched plus profile your JS executor to validate what is blocking/delaying its process. For iOS, make sure you use Safari to debug the JS context using the same JS engine (JSCore). For Android you can use react-native-debugger if you don’t have Hermes enabled, else see this post.

Be careful with Stack navigators stacking too many screens, this can cause memory issues. Plus your global store could cause updates to screens at the back of the stack.

Depending on the problem it might not be optimizable. You can explore options that implement native navigators for slight better performance.

When Global Store Updates

This is also another broad topic. Your state manager of choice has a huge impact on this, and often if they don’t control when to update your connected components you are likely going to need to implement memoize for your state selectors.

During Animations

See Animation section on this.

State Management

If you haven’t learned about the difference of UI state and Server cache please read Kent’s post. State management is made hard because of this confusion.

This is an ever-growing list. See React State Museum for a sense.

We can argue that the growth of so many options is caused by the lack of a solution offered by the React Core team.

For a moment everyone thought this would have been solved with React Context API, nevertheless, the React Core team admitted it is not recommended for states that update frequently.

What options do I recommend?

Zustand

Objective, lightweight, and performant. Its pattern forces you into a good practice of separating your concerns.

Good For

  • Server Cache (Requires you to write entire invalidation/rehydration/update logic)
  • Global UI State (If you can avoid it please avoid it)

Bad For

Nothing really. But, it is likely incompatible with the future suspense API, which is not done.

React-Query

Server Cache solution. It is full of features to deal with server data.

Good For

  • Server Cache (Complete with many features)

Bad For

  • Global UI State

Recoil JS?

Recoil is for UI state that can dynamically grow and updates too frequently. I had to leave a note here about Recoil since it is the current hot thing.

Is Recoil JS fully support React Native?

It “experimentally” does. https://recoiljs.org/blog/2020/10/30/0.1.1-released/

Good For

  • UI State With Frequent Atomic Updates

Atomic updates means updating just a node in your entire React Component tree.

Bad For

  • Server Cache
  • Global State that is non-atomic

I am intentionally omitting many famous libraries, the above two libraries Zustand and React Query would solve 100% of my state management problems

Testing

Jest is the go to framework. You can or not use any helpers.

Since React Native inherits much of the React ecosystem, many liked using Enzyme, but this is not longer a go to choice.

From my experience, Jest plus react-test-renderer is all you need for unit and integration testing on React Native. However, a recent rise in popularity of Kent’s react-testing-library made room for a react-native-testing-library

Unit Testing

  • Jest
  • react-native-testing-library (Optional)

Integration Testing

  • Jest
  • react-native-testing-library (Optional)

End To End Testing

Options:

  • Detox
  • Appium (Recommended)
  • Cavy Cavy a new underdog that implements a end-to-end testing driver fully in JavaScript using React Native APIs.

Upcoming Features

Is Fast Fresh Ready? Yes! See post

Is The New UIManager (Fabric) Ready?

No.

Last official update on fabric https://github.com/react-native-community/discussions-and-proposals/issues/4#issuecomment-569883489

Is JSI Ready?

First part is in master https://github.com/react-native-community/discussions-and-proposals/issues/261

But migration of UIManager to use JSI has not been released into the public.

Is TurboModule Ready?

See https://github.com/react-native-community/discussions-and-proposals/issues/40

Is CodeGen Ready?

There are examples of it working on master, but no official documentation yet.

Hermes is coming to iOS

Tweet by Mike G.

PR

It is included in the v0.64 release candidate. https://github.com/facebook/react-native/releases/tag/v0.64.0-rc.0

Multiple Bundle Support?

This is the ability to have “super apps”. That is, a single app that can dynamically load other apps within it. This idea was popularized by China’s super app like WeChat

Proposal issue

Recent update where someone mentions a solution

Does Hermes Support Intl API?

In November of 2020 work was put in place to support it. A new Hermes release should come with the support soon. See https://github.com/facebook/hermes/issues?q=JS+Intl+support+in+Hermes