1 the introduction

SetState is the most commonly used command of the React framework. It is used to update the status, which is a revolutionary feature of the React framework.

React-dom react-native react-art react-dom react-native react-art

Solve this mystery with the how-does-setstate-know-what-to-do article.

2 an overview

The setState function is called in the react.component. so the most natural association is that the logic for updating the DOM is implemented in the React package.

React works with react-dom react-native react-art packages and even works with react-dom/server on the server side. The React package does not contain DOM update logic.

Therefore, platform-specific UI update logic is distributed in platform-specific packages. The React package only acts as a proxy.

The React engine is not in the React package

Since react 0.14, the engine code has been removed from the React package, which serves only as a general interface abstraction.

In other words, the React package defines the standard state-driven model API, while the React-dom react-native React-Art packages are implemented on their respective platforms.

The platform-specific rendering engine implementation is called Reconciler, and the React-DOM React-Native React-Art implementation for the three packs is available via this link.

This shows that the React package only tells you what syntax react has, not how to implement it, so we need to use the React package with react- XXX.

For context, the React package simply defines the following:

// A bit simplified
function createContext(defaultValue) {
  let context = {
    _currentValue: defaultValue,
    Provider: null.Consumer: null
  };
  context.Provider = {
    ? typeof: Symbol.for("react.provider"),
    _context: context
  };
  context.Consumer = {
    ? typeof: Symbol.for("react.context"),
    _context: context
  };
  return context;
}
Copy the code

It’s up to the React-DOM and React-Native to decide how to implement the MyContext.Provider API.

Fail saying these types are invalid because the API definition and implementation do not match.

How does setState call the platform implementation

Each platform’s implementation of the UI update logic is encapsulated in the updater function, so the platform code adds its own updater implementation to the component:

// Inside React DOM
const inst = new YourComponent();
inst.props = props;
inst.updater = ReactDOMUpdater;

// Inside React DOM Server
const inst = new YourComponent();
inst.props = props;
inst.updater = ReactDOMServerUpdater;

// Inside React Native
const inst = new YourComponent();
inst.props = props;
inst.updater = ReactNativeUpdater;
Copy the code

Unlike props, updater cannot be called directly because the REACT API is called by the React engine at setState:

// A bit simplified
setState(partialState, callback) {
  // Use the `updater` field to talk back to the renderer!
  this.updater.enqueueSetState(this, partialState, callback);
}
Copy the code

React -> setState -> updater < -react -dom

Hooks

Hooks work similarly to setState; when useState or useEffect are called, they are internally called as follows:

// In React (simplified a bit)
const React = {
  // Real property is hidden a bit deeper, see if you can find it!
  __currentDispatcher: null,

  useState(initialState) {
    return React.__currentDispatcher.useState(initialState);
  },

  useEffect(initialState) {
    return React.__currentDispatcher.useEffect(initialState);
  }
  // ...
};
Copy the code

ReactDOM provides __currentDispatcher (shorthand) :

// In React DOM
const prevDispatcher = React.__currentDispatcher;
React.__currentDispatcher = ReactDOMDispatcher;
let result;
try {
  result = YourComponent(props);
} finally {
  // Restore it back
  React.__currentDispatcher = prevDispatcher;
}
Copy the code

As you can see, Hooks work in much the same way as setState, but note that react and react-dom pass dispatches between them, although you can’t see them. But this dispatch must correspond to a unique React instance, which is why Hooks don’t allow multiple React instances to be loaded at the same time.

Like updater, Dispatcher can be overwritten by platform implementations, such as react-Debug-hooks.

ReadContext, useCallback, useContext, useEffect, useImperativeMethods, useLayoutEffect, useMemo, useReducer UseRef and useState are fairly large projects, so it is recommended that you understand the basic architecture, unless you want to be deeply involved in the React ecosystem.

3 intensive reading

Unlike other React analysis articles, this paper does not get too close to the reconciler’s implementation, but asks a fundamental question: Why does setState come from the React package, but the implementation is in the React dom? How does React implement this magic?

With this question, we learned about React’s higher abstraction capabilities, how to use one package to make the specification and use n-packages to implement it.

The power of interfaces

Interfaces also have great power in everyday programming. Here are a few examples.

UI components span three interfaces

Due to some deficiencies of RN, Weex and Flux, more and more people choose the way of “three-terminal implementation of one idea” to make cross-three-terminal UI components, which not only gives consideration to performance, but also takes account of platform differences and makes customized optimization for details of components on different platforms.

The biggest problem with implementing this solution is interface conventions. The three implementations must follow the same SET of API interfaces, so that business code can be “written for any platform and automatically ported to other platforms”.

A common approach is to fix the input and output of components through a uniform set of API file constraints, and implement platform-specific components for different platforms. The idea is very much the same as React.

Of course, RN frameworks themselves are also typical implementations of the same interface on different platforms, but the implementation is not thorough enough. The communication between JS and Native leads to inferior performance as the source.

Universal data query service

Generic data query services are also popular, allowing users to query data from various types of databases through a single set of SQL by smoothing out the syntax of each database.

In this scenario, a common query syntax, similar to the React API, is translated into the SQL dialect of each database platform during execution.

Small program fusion scheme

This scheme is very popular now. One-click publishing to platform applets via template – or JSX-based syntax.

Such a scheme would certainly abstract a set of generic syntax, almost equivalent to react versus React – DOM: all conforming syntax is translated into implementations of various applets.

4 summarizes

There is a big difference between this platform implementation and the cross-platform implementation, as the JAVA Virtual machine is essentially a set of implementation solutions. A platform-specific implementation, which delivers the most native performance and experience, also has the most constraints, should have an API that is a subset of all platform support.

In addition, this solution can be used not only for one set of specifications, different platform implementations, but even for “one platform implementation”.

There are many duplicate wheels or platforms in both the company and the open source industry. If the technical committee agrees on a set of platform implementation specifications and everyone follows this specification to develop the platform, it will be easier to do convergence in the future, or the first step of convergence is to unify the API specifications first.

This leaves one question to consider: are there any examples of ideas that use the setState specification to separate implementation? Feel free to leave your answers.

What does setState Do · Issue #122 · dt-fe/weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.