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

  1. The createElement method;
  2. Render.
  3. Concurrent mode;
  4. Fibers;
  5. Render and submit;
  6. Coordination;
  7. Function component;
  8. Hooks;
  9. 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

  1. Pomb. Us/build – your -…

  2. react.iamkasong.com/

5. Relevance

2.render: juejin.cn/post/702031…