React Native Basics: A complete glossary of React Native and architecture terms to help you stay in the know for when developers throw a lot of terms at you.
Credit for this post is given to Parashuram of the React Native Core Team @ Facebook. This was posted with permission to make it easier to find via Medium. His original post can be found here.
As the React Native team is working on the new architecture, there have been a few terms used to describe the various pieces. This post aims to clarify some of the terms and points to places in the repository with relevant code.
- The bridge is also tied to the lifecycle of React Native. Starting or stopping React Native usually means that the bridge is initialized or torn down.
To explore the bridge in more concrete terms, we can install a MessageSpy to look at the exact bytes that are sent back and forth. Also note that while the bridge is async, we can use @ReactMethod(isBlockingSynchronousMethod = true) for one-off synchronous method calls.
Instead of using the bridge for queuing messages, the new architecture allows us to directly “invoke” (think RPC) Java/ObjC methods.
The snippet below shows a simple usage of JSI and how we could expose Java/ObjC objects to JS.
Most of the code for JSI resides in the jsi folder in React Native and is written in C++.
Fabric was the first part of the re-architecture that was announced. While it only deals with the user interface of the new architecture, it is sometimes wrongly used to refer to the entire re-architecture work.
In the current architecture, all UI operations (like creating native views, managing children, etc). are handled by a native module called UIManagerModule. The React Reconciller sends UI commands over the bridge, which are eventually handled by this module and delegated to UIImplementation. This in turn creates shadow nodes that represent the layout tree and are passed to Yoga to determine the relative co-ordinates based on the Flex box styles that are passed in from JS.
In the new system,
- We expose a JSI object a top level “Native Module Proxy”, called global.__turboModuleProxy.
- To access a native module, say SampleTurboModule, application code will then call in require(‘NativeSampleTurboModule’).
- Inside NativeSampleTurboModule.js, we call TurboModuleRegistry.getEnforcing() which then calls the global.__turboModuleProxy(“SampleTurboModule”)
- Calling global.__turboModuleProxy function triggers the JSI function that we exposed in Step 1. This is where the platform divergence happens.
- We invoke a getModule function that is defined for Java and ObjC. This function takes in a string, and returns a JSI object for the specific TurboModule.
- To get a TurboModule JSI object, we first get the Java/ObjC implementation and then create JSI object from it.
Like in the current architecture, most types including boolean, strings, Maps, Arrays, Callbacks and Promises are supported.
In terms of timelines, most of the JSI code has already landed in the repository at the time of writing this post. A lot of the Fabric code is also in the repository, and updates to TurboModules continue to roll out. Since this is a mostly backward compatible, there does not have to be a single date of release, but more of a gradual rollout. You can follow the React Native repository, and the issues about Fabric and TurboModules for updates.