1. Preface:
In this paper, we write a simple version of React to have an intuitive understanding of the basic principle of React.
The implementation is version 16.8, based on pomb.us/build-your-… ;
React is a prerequisite for learning.
2. Achieve your goals
- The createElement method;
- Render.
- Concurrent mode;
- Fibers;
- Render and submit;
- Coordination;
- Function component;
- Hooks;
- Class components
Learning advice: download the code in this section, check the article, and try to implement it again.
CreateElement implementation
3.1 thinking
Before React17, we used to introduce React code. If we didn’t introduce React code, we would get an error. We didn’t use React in our code. So with that in mind we move on;
import React from 'react'
Copy the code
3.2 Element variable parsing
Let’s create an element variable and place this code on Babel to see the result:
const element = <h1 title="foo">Hello</h1>
Copy the code
throughbabelIt compiles to the following form:
The compiled code is as follows:
const element = React.createElement("div", {
title: "foo"
}, "Hello");
Copy the code
Element Parameter Description:
- Dom elements
- attribute
- The children sub-elements
Use React to parse JSX. If React is not introduced, this code will fail. JSX is actually a syntactic sugar that really needs to be parsed into JS code to execute;
3.3 Creating a Project
Let’s create the execution command first:
npm init
Copy the code
Installation-related dependencies:
npm install --save-dev babel-loader @babel/core
npm install webpack --save-dev
npm install --save-dev @babel/preset-react
npm install --save-dev html-webpack-plugin
Copy the code
Create project directory:
Webpack configuration:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
main: './src/index.js'
},
devServer: {
port: 9000,},module: {
rules: [{test: /\.js$/,
use: {
loader: 'babel-loader'.options: {
presets: ['@babel/preset-env'].plugins: ['@babel/plugin-transform-react-jsx']}}}]},mode: "development".optimization: {
minimize: false
},
plugins: [
new HtmlWebpackPlugin({
title: 'React',})],}Copy the code
Add startup commands:
3.4 Printing the Value
Create a real React project using create-react-app. The installation process is not described in this article. What does react. createElement actually generate? Print element:
import React from 'react';
import ReactDOM from 'react-dom';
const element = <h1 title="foo">Hello</h1>
console.log(element)
const container = document.getElementById("root")
ReactDOM.render(element, container)
Copy the code
Print result:
To simplify, strip out the other attributes (we don’t care about the other attributes) :
const element = {
type: "h1".props: {
title: "foo".children: "Hello",}}Copy the code
To recap, react. createElement actually generates an Element object with two properties, type and props. This object has the following properties:
Element object parameters:
- Type: indicates the label name
- Props: attribute
- Title: Indicates the attribute of the label
- Children: child attribute
Simple process
Take a look at render’s simple flow in advance:
Reactdom.render () adds element to a DOM node with id root. We’ll implement this method instead of reactdom.render () in the React source code;
Sample code:
const element = {
type: "h1".props: {
title: "foo".children: "Hello",}}Copy the code
1. First, we create a node (element.type) using the element type, in this case h1;
const node = document.createElement(element.type)
Copy the code
2. Set the node property to title.
node["title"] = element.props.title
Copy the code
3. With only one string as a child node, we create a text node and set its nodeValue to element.props. Children;
const text = document.createTextNode("")
text["nodeValue"] = element.props.children
Copy the code
4. Finally, we attach textNode to h1 and h1 to the container;
node.appendChild(text)
container.appendChild(node)
Copy the code
3.6 createElement Implementation (Virtual DOM)
Implement React code with our own code;
CreateElement creates an Element object:
const element = {
type: "h1"./ / label
props: {
title: "foo"./ / property
children: "Hello"./ / the node}},Copy the code
Call method:
const element = React.createElement("div", {
title: "foo"
}, "Hello");
Copy the code
Based on the call and the return result, design the createElement function as follows:
// react/createElement.js
/** * Create a virtual DOM structure@param {*} The type label *@param {*} Props attribute *@param {... any} Children themselves@returns Virtual DOM structure */
export function createElement(type, props, ... children) {
return {
type,
props: {
...props,
children: children.map(child= >
typeof child === "object"
? child
: createTextElement(child) // It is a text node),}}}/** * Create a text node * when children are non-objects@param {*} Text Indicates the text value *@returns Virtual DOM structure */
function createTextElement(text) {
return {
type: "TEXT_ELEMENT".props: {
nodeValue: text,
children: [],},}}Copy the code
To visualize this, let’s change the element structure:
const element = (
<div id="foo">
<a>bar</a>
<b />
</div>
)
Copy the code
Test it out:
// src/index.js
import React from '.. /react';
const element = (
<div id="foo">
<a>bar</a>
<b />
</div>
)
console.log(element
Copy the code
Print result:
3.7 Code in this section
Address: gitee.com/linhexs/rea…
4. Reference links
-
Pomb. Us/build – your -…
-
react.iamkasong.com/
5. Relevance
2.render: juejin.cn/post/702031…