开源日报每天推荐一个 GitHub 优质开源项目和一篇精选英文科技或编程文章原文，坚持阅读《开源日报》，保持每日学习的好习惯。
今日推荐英文原文：《React: You are Using useEffect() Wrong, Do This Instead》
推荐理由： freeapi是一个单一源API 管理中心，用于学习任何编程语言中的api处理， 也用freeapi在Web和移动应用程序中构建自己前端作品集
推荐理由：React Native的新架构引入了重大变化 主要组件包括：
Fabric: 一种新的渲染系统，取代了UI Manager，实现了JS和UI线程之间的同步。它提升了用户交互（如滚动和手势）的性能，将同步执行重点放在面向用户的任务上
ReactNative New vs. Old Architecture
ReactNative Multi platform application Development.
This is a good time to understand what changes are taking place under the hood and how they might affect your React Native App.
This article aims to cover the most important changes.
- Turbo Modules
Before we get to the new architecture, let’s recap how the old one works.
How the UI of a React Native app is rendered.
- Communication between Components: In React Native, you build your UI using components. Components communicate with each other through properties (props) and callbacks. This follows a one-way flow, making it easier to manage data flow in your app.
- Passing Data: If a parent component needs something from its child, it passes down a callback. Similarly, if a child component needs something from its parent, it receives a property. This unidirectional flow simplifies the design and maintenance of your app.
The Bundling Process
A native mobile app will be developed using the programming language that is specific to that platform. When developing with React Native, you can pretty much get by without writing any Objective C/Java code — unless you are required to do something that is not covered by the library, such as integrating a payment provider that only offers SDKs for Android and iOS.
However, any React Native project contains an
ios directory and an
android one. These directories act as the entry points for each platform — they basically bootstrap React Native. They contain code that is specific to each platform, and here’s where your JS code is bridged for each platform.
In order to start your app, you’ll generally run
yarn android or
yarn ios and then you’ll wait until the app magically opens on your desired device. But what happens while you wait?
As soon as you type in one of those commands (which are
react-native run-android and
react native run-ios, respectively) you start up the packager. One such packager is Metro. The packager takes all your JS code and puts it into a single file:
main.bundle.js. When your app finally opens on your phone, the phone will look in the place that’s familiar to it: either the
android or the
main.bundle.js will then be run on this thread.
The React Native Bridge
How Performance Is Affected
What is cool about React Native (in comparison to other platforms such as Cordova) is that it doesn’t run its code inside of a
WebView. It uses native views.
This advantage means that we’ll be able to develop smooth and fast apps that can run at 60 FPS. If you modify the state of a component that is very high in the tree (and you didn’t dedicate too much time to prevent useless re-renders), then the whole component tree will be re-rendered. This won’t be visible to the user in most cases. However, if those descendants are computationally expensive, then you’ll notice your app stuttering for a little bit.
In a nutshell:
The Execution of React Native apps happens over three threads:
- The Native/UI thread: used to run the Native Modules and to handle operations like UI Rendering, user gesture events etc.
- Additionally there is a 3rd thread called the shadow thread, which is used to calculate the Layout of Elements before rendering them on the host screen
The Communication between the JS and Native Threads is carried over an entity called the bridge. When sending data through the bridge it has to be batched(optimized) and serialized as JSON. This bridge can only handle asynchronous communication.
Old Architecture in React native
Yoga: It is the name of a Layout engine, which is used to calculate positions of UI elements for the user’s screen.
In the old architecture, React Native uses the Bridge Module to make communication possible between the JS and Native threads. Every time data is sent across the bridge, it has to be serialized as JSON. When the data is received on the other side it must be decoded as well.
Another important point to note is; messages send over the bridge are asynchronous in nature, which is a good thing for most use cases, but there are certain instances when JS code and native code needs to be in sync.
Let’s take an example to better understand the bridge:
- JS thread prepares message for the Native Thread
- It is serizlized as JSON before sending across the bridge
- It is decoded when recieved on the other end of the bridge
- Then the native thread executes the required native code
What does general-purpose mean?
const container = document.createElement(‘div’);
Another big advantage of the JSI is that it is written in C++. With the power of C++ React Native can target large number of Systems like Smart TVs, Watches etc.
Fabric is the rendering system, which will replace the current UI Manager.
To understand the advantages of Fabric, first let’s look at how UI is currently rendered in React Native:
This shadow Tree is used by the Layout Engine to calculate the positions of UI elements for the host screen. Once the results of the Layout calculation are available, the shadow tree is transformed into HostViewTree, which comprises of Native Elements. (For example The ReactNative
Problems with this approach:
As we know, all the communication between threads happens over the bridge. Which means slow transfer rates, and unnecessary copying of data.
For Example: If a ReactElementTree Node happens to be an
That’s not all. Since the JS and UI threads are not in sync, there are certain use cases when your app can seem laggy as it drops frames. (Example: Scrolling through a FlatList with a huge list of data)
What is Fabric?
According to the official ReactNative documentation,
“Fabric is React Native’s new rendering system, a conceptual evolution of the legacy render system”
What are the benefits of Fabric?
With the new rendering system, user interactions such as scrolling, gestures, etc can be prioritized to be executed synchronously in the main thread or native thread. While other tasks such as API requests will be executed asynchronously.
That’s not all. The new Shadow Tree will be immutable, and it will be shared between the JS and UI threads, to allow straight interaction from both ends.
As we have seen, in the old architecture React Native has to maintain two hierarchies/DOM nodes. But since the shadow tree will now be shared among realms, it will help with reducing memory consumption as well.
3. Turbo Modules
That’s why the new architecture will also include a static type checker called CodeGen.
If we combine all the changes, the new architecture will look like this:
Here the key highlights are:
• Bridge will be replaced by JSI
• Complete Interoperability between all threads
- Web-like Rendering system
- Time-sensitive tasks can be executed synchronously
- Lazy Loading of Turbo Modules
- Static Type Checking for compatibility between JS and Native Side.
this new structure will give React Native some powerful improvements.