2
头图

Hi everyone, I'm Kasong.

React can be seen as a combination of three parts:

  • scheduler , scheduler, used to schedule tasks
  • reconciler , the coordinator, used to calculate the side effects caused by the task
  • renderer , renderer, used to perform side effects in the host environment

These three are all independent packages. The ReactDOM introduced in our project can be seen as a package of the following three parts of code:

  • The main logic of scheduler
  • reconciler partial logic
  • The main logic of ReactDOM renderer

This article will teach you how based on the official reconciler , implement mini ReactDOM .

This article refers to Hello World Custom React Renderer

Project initialization

Create a project through CRA (or use an existing project):

create-react-app xxx

Create a new customRenderer.js , introduce react-reconciler and complete the initialization:

// 本文使用的reconciler版本是0.26.2
import ReactReconciler from 'react-reconciler';

const hostConfig = {};
const ReactReconcilerInst = ReactReconciler(hostConfig);

Among them, hostConfig is the configuration item of the host environment.

Finally, customRenderer.js exports an object render

export default {
  render: (reactElement, domElement, callback) => {
    // 创建根节点
    if (!domElement._rootContainer) {
      domElement._rootContainer = ReactReconcilerInst.createContainer(domElement, false);
    }

    return ReactReconcilerInst.updateContainer(reactElement, domElement._rootContainer, null, callback);
  }
};

In the project entry file, replace ReactDOM our implementation of CustomRenderer :

import ReactDOM from 'react-dom';
import CustomRenderer from './customRenderer';

// 替换ReactDOM
CustomRenderer.render(
  <App />,
  document.getElementById('root')
);

Implement ReactDOM

Next, we implement the hostConfig configuration, first fill in the empty function to avoid application errors:

const hostConfig = {
  supportsMutation: true,
  getRootHostContext() {},
  getChildHostContext() {},
  prepareForCommit() {},
  resetAfterCommit() {},
  shouldSetTextContent() {},
  createInstance() {},
  createTextInstance() {},
  appendInitialChild() {},
  finalizeInitialChildren() {},
  clearContainer() {},
  appendInitialChild() {},
  appendChild() {},
  appendChildToContainer() {},
  prepareUpdate() {},
  commitUpdate() {},
  commitTextUpdate() {},
  removeChild() {}
}

Note that there is the only configuration item Boolean supportsMutation , which means that the API host environment supports mutation .

This is DOM API works, such as element.appendChild , element.removeChild . If it is Native environment, it is not this way of working.

Next we will implement these API .

Implement API

These API can be divided into the following categories.

Initialize environment information

getRootHostContext and getChildHostContext used to initialize context information.

Generate DOM nodes

  • createInstance used to create DOM nodes
  • createTextInstance used to create text nodes

You can createTextInstance as follows:

createTextInstance: (text) => {
  return document.createTextNode(text);
}

Judgment of key logic

shouldSetTextContent used to determine whether the children component is a text node. The implementation is as follows:

shouldSetTextContent: (_, props) => {
    return typeof props.children === 'string' || typeof props.children === 'number';
},

DOM manipulation

appendInitialChild used to insert the DOM node, which is implemented as follows:

appendInitialChild: (parent, child) => {
  parent.appendChild(child);
},

commitTextUpdate used to change the text node, which is implemented as follows:

commitTextUpdate(textInstance, oldText, newText) {
  textInstance.text = newText;
},

removeChild used to delete child nodes, which is implemented as follows:

removeChild(parentInstance, child) {
  parentInstance.removeChild(child);
}

When all API implemented, the page can be rendered normally:

For the complete Demo see: complete Demo address

Summarize

After studying in this article, we have implemented a simple ReactDOM .

If you want you can draw any UI environment using React , you can use react-reconciler achieved in this environment React .

For example, Introduction To React Native Renderers teaches you how to implement React Native environment.

Welcome to join human high-quality front-end framework group , take flight


卡颂
3.1k 声望16.7k 粉丝