Hi everyone, I'm Kasong.
React
can be seen as a combination of three parts:
scheduler
, scheduler, used to schedule tasksreconciler
, the coordinator, used to calculate the side effects caused by the taskrenderer
, 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 nodescreateTextInstance
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。