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.
Table of Contents
- Accessibility
- Animation
- Companies
- Component Libraries
- Features
- Navigation
- Native Modules
- Supported Platforms
- Performance
- State Management
- Testing
- Upcoming Features
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.
Navigation
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 iOSIt 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
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