1. React-native style
In the last article, we should already have a certain concept of cross-platform, but there is actually a problem that has not been solved here, that is, the styles on ios and Android are actually different, so our Rn needs to smooth out this difference. rn uses css-in-js.
The style object we write in js will be processed by a separate thread, which is the Shadow thread. In this thread, the Yoga engine (which is also developed by Facebook) recalculates the layout of app. After calculating the things about app, this engine feeds the results back to the UI thread and finally presents them.
Then the architecture of a complete old version is like this:

Then let’s sort out the whole process now: Suppose we now have a piece of react code
<View style={{width: 200, height: 200}}/>
The next step is for the js thread to serialize it
UIManager.createView([352,"RCTView",191,{width":200,"height":200}])
At this time, this task enters the asynchronous queue in front of the bridge, and its destination is ShadowThread. After receiving this information, ShadowTread first deserializes it to form a Shadow tree, and then passes it to Yoga to form the native layout information.
The next step is to serialize the information and pass it to the native thread, and then deserialize it to render and draw based on the layout information.
Everyone should now have a basic understanding of the overall architecture of an rn. Do you still remember the question in the last article? Loads and async of bridge can cause performance issues and uncertainty.
-
The transmission of thread information needs to be serialized repeatedly every time to reduce overhead, but serialization is a very expensive thing.
-
The uncertainty of asynchronous queues, you cannot guarantee the order of an event.
Therefore, the new architecture of rn is to solve these problems, which is the current middle layer.
2. React-native new architecture
There is a lot of content about the new architecture, and I may not understand it properly in some places. I welcome your corrections.
Let’s talk about the biggest change first, which is that rn directly killed the old bridge in the new architecture and directly replaced it with a new middle layer or general layer, which is JS Interface (JSI). There is a lot of new content in this general layer. We can take a look at this architecture diagram first.

So, let’s take a look at the changes. The middle part of the picture above is JSI. (Explain why this picture is like this, because I actually think Turbo Modules is an enhancement of Native Moodles, and Fabric is an enhancement of Renderer, they already exist).
-
JS-bundleis no longer strongly dependent on theJavaScriptCoreengine. We can now easily replace it with a better engine with better performance. For exampleHermes. -
JSIallows us to callnativemethods directly in thejslayer. Implemented byHostObject C++ object, it directly stores references tonativelayer methods and properties on a global object, and then ourjscan directly calljava/oc api. -
The emergence of
Turbo Modules(Native Mudles in the picture above). In the previous architecture, allNative Modulesused byJS(such as Bluetooth, geolocation, file storage, etc.) must be initialized before the application is opened, which means that even if the user does not need some modules, it still must be initialized at startup.
Turbo Modules are basically enhancements to these old Native modules. As mentioned before, now JS will be able to hold references to these modules, so JS code can only load the corresponding modules when needed, which can significantly shorten the startup time of RN applications.
Fabricis therendererin the picture above (previously the shadow layer was implemented in the native layer), a newUI renderer, which is equivalent to directly creating aShadowTreein C++. One is faster and also reduces the steps of rendering elements.
Maybe you don’t understand, for example: when App is running, React will execute your code and create a ReactElementTree in JS, based on this tree renderer will create a ReactShadowTree in C++. Fabric will use Shadow Tree to calculate the position of UI elements, and once Layout is completed, Shadow Tree will be converted into HostViewTree composed of Native Elements (for example: in RN will become ViewGroup in Android and UIView in iOS).
codegenis actually a static type checker.CodeGenuses typedJavaScriptto define interface elements forTurbo ModulesandFabricfor their use, and it will generate morenativecode at compile time instead of runtime.
3. Rendering of RN
Rendering React code to the host platform is called the rendering pipeline, which can be roughly divided into three stages:
-
Rendering (
Render): InJavaScript,Reactexecutes the business logic code to createReactelement trees (React Element Trees). Then inC++, use theReactelement tree to create aReactshadow tree (React Shadow Tree). -
Commit (
Commit): After theReactshadow tree is completely created, the renderer will trigger a commit. This will promote theReactelement tree and the newly createdReactshadow tree to the "next tree to mount". This process also includes layout information calculation. -
Mount (
Mount): After theReactshadow tree has the layout calculation result, it will be converted into a host view tree (Host View Tree).
4. Some basic libraries
Ok, the above is all about the architectural design of the framework. We first have a general concept, and now we get a little closer to the actual practice to understand some necessary packages, because we won’t talk about it later.
React-native only has some necessary built-in packages, but in order to reduce the size of the package as much as possible, many packages need to be configured by yourself, such as asyncStorage. For this kind of sdk, you need to rely a little bit on related native knowledge, but it is not a big problem. Generally, there will be a template to teach you, just follow the template (but not necessarily, in most cases). So let’s take a look at some commonly used packages now.
3.1, React Navigation
This should be something that almost every student who uses rn should understand. The routing of native app and web are different. In app, there is actually no concept of url. In native screen, you need to understand screen, which means to control the screen that the user sees. In the old version of rn there were some primitive navigation components to control the screen, but they were very complicated, so now the library react-navigation is generally used.
Let me go straight to the actual combat.
import * as React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import Home from "./Home";
import Settings from "./Settings";
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Settings" component={Settings}/>
</Stack.Navigator>
</NavigationContainer>
);
}
createNativeStackNavigator is a method to create your navigation component. It returns an object with two components, Screen and Navigator, which are used to configure navigation.
import React from "react";
import { View, Text, Button, StatusBar } from "react-native";
import styles from "./styles";
export default function Home({ navigation }) {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<Text>Home Screen</Text>
<Button
title="Settings"
onPress={() => navigation.navigate("Settings")}
/>
</View>
);
}
Just see the home component. When you press it, it will jump to the settings screen. We will talk about more content later in the actual combat. It is just a simple demonstration.
3.2 RN component library
antd mobile estimates that in China we basically use this or our own packaged component library. We recommend several other NativeBase, React Native Element, UI Kittern, React-native-paper
3.3 Start page
In fact, the startup page is the transition page displayed before your js thread starts, React-native-bootsplash.
3.4 Icon
react-native-vector-icons, react-native-svg.
3.5 Exception catching
Normally, when we develop a web application, we handle errors well because they don't go outside the scope of JS. Simply put, our front-end is the king (control) of the web. We can easily see the reason and open the log in DevTools.
But Rn is because in addition to the JS of the environment, we also have native components, which may also cause errors in app execution. So when an error occurs, our application will shut down immediately and it is difficult to figure out the reason, so React-native-exception-handler is also the package to solve this problem.
Like this:
import { setJSExceptionHandler, setNativeExceptionHandler } from "react-native-exception-handler";
setJSExceptionHandler((error, isFatal) => {
//…
});
const exceptionhandler = (exceptionString) => {
//Exception handling code
};
setNativeExceptionHandler(
exceptionhandler,
forceAppQuit,
executeDefaultHandler
);
3.6 package update
In fact, if it is iOS and we want to update the application and upload it to the store, there is such a technology OAT that can replace the js package, you can look at Microsoft's Codepush
4. End
rnChinese document address, these two articles are all about some basic theoretical things. For some component APIs, you can read the documentation. Woo! Do you want to be strong? Then come and learn together, ->Look at the boiling point here.