Rendering principle

Render: Generate objects for display and form these objects into real DOM objects

  • React Element: React Element, created with React. CreateElement (syntax sugar: JSX)
    • Such as:
    • The < div > < h1 > title < / h1 > < / div >
    • <App />
  • React node: Objects that are specifically used for rendering to the UI. React elements are used to create React nodes. The ReactDOM must be rendered using React nodes
  • Node type:
    • React DOM node: The React element type that creates this node is a string
    • React component node: The React element type that creates the node is either a function or a class
    • React text node: Created from strings and numbers
    • React Empty node: null, undefined, false, true
    • React array node: This node is created from an array
  • Real DOM: THE DOM element created with document.createElement

First render (new node render)

  1. Creates a node from the value of the parameter
  2. Do different things for different nodes
    1. Text node: Create a real text node with document.createTextNode
    2. Empty node: do nothing
    3. Array nodes: Iterate through the array, recursively creating nodes for each item in the array (go back to Step 1 and repeat until the iteration is complete)
    4. DOM node: Create a real DOM object with document.createElement, immediately set the properties of the real DOM element, and iterate over the Children property of the React element recursively (go back to Step 1 and repeat until the loop is complete).
    5. Component node
      1. Function component: Call a function (which must return something that can generate a node) and recursively generate a node with the result of that function (go back to step 1 and repeat until the traversal is complete)
      2. Types of components:
        1. Create an instance of the class
        2. Call the lifecycle method of the object immediately: static getDerivedStateFromProps
        3. Run the Render method on that object to get the node object (recurse the node, go back to Step 1 and repeat)
        4. The component’s componentDidMount is added to an execution queue (fifO, fifO, fifO) that executes when the entire virtual DOM tree has been built and real DOM objects have been added to the container
  3. Once you have generated the virtual DOM tree, save it for later use
  4. Add the actual DOM object you generated earlier to the container.
const app = <div className="assaf">
    <h1>Title {[" ABC ", null,<p>The paragraph</p>]}
    </h1>
    <p>
        {undefined}
    </p>
</div>;
ReactDOM.render(app, document.getElementById('root'));
Copy the code

The above code generates a virtual DOM tree:

function Comp1(props) {
    return <h1>Comp1 {props.n}</h1>
}

function App(props) {
    return (
        <div>
            <Comp1 n={5} />
        </div>
    )
}

const app = <App />;
ReactDOM.render(app, document.getElementById('root'));
Copy the code

The above code generates a virtual DOM tree:

class Comp1 extends React.Component {
    render() {
        return (
            <h1>Comp1</h1>)}}class App extends React.Component {
    render() {
        return (
            <div>
                <Comp1 />
            </div>)}}const app = <App />;
ReactDOM.render(app, document.getElementById('root'));
Copy the code

The above code generates a virtual DOM tree:

Update the node

Updated scenarios:

  1. Reactdom. render is called to trigger the root update
  2. Calling setState on an instance object of a class component causes the node on which the instance is located to update

Node update

  • If reactdom. render is called, enter the diff update of the root node
  • If I call setState
      1. Run the lifecycle function, static getDerivedStateFromProps
      1. Run shouldComponentUpdate, and if the function returns false, terminate the current process
      1. Run Render to get a new node and enter the comparison update for that new node
      1. Queue the life cycle function getSnapshotBeforeUpdate for future execution
      1. Queue the life cycle function componentDidUpdate for future execution

Follow-up steps:

  1. Update the virtual DOM tree
  2. Complete the actual DOM update
  3. Call componentDidMount in the execution queue in turn
  4. Call getSnapshotBeforeUpdate in the execution queue in turn
  5. Call componentDidUpdate in the execution queue in turn

Compared to update

Compare the newly generated node with the node in the previous virtual DOM to find the difference and complete the update

Question: Compare which node in the DOM tree before

React makes the following assumptions to improve comparison efficiency

  1. It is assumed that there will be no hierarchical movement of nodes (for comparison, directly find nodes at corresponding positions in the old tree for comparison)
  2. Different node types generate different structures
    1. Same node type: The nodes themselves are of the same type. If they are generated from the React element, the type value must also be the same
    2. The others belong to different node types
  3. Multiple brothers identify the new node for comparison by a unique key

Functions of the key value: It is used to find the corresponding new node through the old node. If an old node has a key value, it will find nodes with the same key value in the same hierarchy for comparison when it is updated.

The key value should be unique in a range (among sibling nodes) and should remain stable

Find a target for comparison

Check whether the node types are consistent

  • consistent

Do different things for different node types

Empty node: does nothing

DOM node:

  1. Reuse the real DOM object directly
  2. Record changes to its properties for future updates (no real changes now)
  3. Iterate over the children of the new React element, updating by recursive comparison

Text node:

  1. Reuse the real DOM object directly
  2. Record the new text changes for future updates

Component node:

Function component: re-call the function, get a node object, enter the recursive comparison update

Types of components:

  1. Reuse the previous instance
  2. Call the lifecycle method getDerivedStateFromProps
  3. Call the lifecycle method shouldComponentUpdate, and terminate if it returns false
  4. Run Render to get the new node object and enter the recursive comparison update
  5. Queue the getSnapshotBeforeUpdate of this object
  6. Queues the object’s componentDidUpdate

Array nodes: Iterate over the array for recursive comparison updates

  • Don’t agree

In general, uninstall the old node and create a new node

Creating a New node

The process for mounting the new node is displayed

Uninstalling the old node

  1. Text node, DOM node, array node, empty node, function component node: discard the node directly, and recursively unload the node if it has child nodes
  2. Class component node:
    1. Discard the node directly
    2. Call the componentWillUnMount function for this node
    3. Unload child nodes recursively

There is no target for comparison

Nodes in the new DOM tree have been deleted

Nodes are added to the new DOM tree

  • Create a newly added node
  • Unmount redundant old nodes