Github address: github.com/RainyNight9…

React works

1.1. Virtual DOM

React Virtual DOM What about diff?

When you get a question, what’s the usual answer? Why is that? How to do? Then follow this train of thought!

what

DOM information and structure are represented by JavaScript objects, which are re-rendered when the state changes. This JavaScript object is called the Virtual DOM;

why

DOM manipulation is slow, and even minor manipulation can cause pages to be reformatted, which can be very costly. Js objects are faster and simpler to process than DOM objects. The diff algorithm is used to compare the differences between the old and new VDOM, so that DOM operations can be performed in batches and minimized, thus improving performance.

where

React uses JSX syntax to describe views. When translated by babel-loader, they become react.createElement (…). This function will generate a VDOM to describe the real DOM. In the future, if the state changes, VDOM will make corresponding changes, and then diff algorithm will be used to compare the difference between the old and new VDOM to make the final DOM operation.

Speaking of JSX, here is a quick overview:

What is the JSX

React uses JSX instead of regular JavaScript. JSX is a JavaScript syntax extension that looks a lot like XML.Copy the code

Why do YOU need JSX

Development efficiency: Using JSX to write templates is simple and fast. Execution efficiency: JSX is optimized for faster execution when compiled into JavaScript code. Type safety: Errors are found during compilation.Copy the code

The React principle of 16

Babel-loader precompiles JSX to react.createElement (...)Copy the code

The React principle of 17

The JSX conversion in React 17 does not convert JSX to React. CreateElement. Instead, it automatically introduces new entry functions from the React package and calls them. The JSX syntax will not change and the old JSX transformations will continue to work.Copy the code

Similarities and differences with Vue

The virtual DOM + JSX in React was designed from the beginning, while vUE was an evolution, appearing after version 2.0.

JSX is js extension, the escape process is simple and direct; The vue process of compiling a template into a render function requires a complex compiler to convert string-ast-js function strings

1.2 Render, Component basic core API

render

ReactDOM.render(element, container[, callback]);
Copy the code

When first called, all DOM elements in the container node are replaced, and subsequent calls are efficiently updated using the React DOM Diffing algorithm.

If an optional callback function is provided, the callback will be executed after the component has been rendered or updated.

The node type

1, text node 2, HTML tag node 3, function component 4, class component...Copy the code

Function component

Function Welcome(props) {return <h1>Hello, {props. Name}</h1>}Copy the code

Class components

The React component can be defined as a class or function. To define a class component, you need to inherit react.component.react.pureComponent:

class Welcome extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>
    }
}
Copy the code

1.3. Handwritten version of MyReact

Implement the first rendering of native label nodes, text nodes, function components and class components

Create a React project with the Create React App, install the dependencies, and run them.

Add this code to SRC /index.js to check the version number and make sure you have version 17

console.log("version", React.version);
Copy the code

Since React automatically replaces JSX with js objects in React17, we mainly need to comment out SRC /index.js:

// import React from "react";
// import ReactDOM from "react-dom";
Copy the code

Then create a myreact folder under SRC and create a react-dome.js inside

// vNode virtual DOM object // node real DOM node //! Function render(vnode, container) {// react17 can automatically render("vnode", vnode); // vnode->node const node = createNode(vnode); // node->container container.appendChild(node); Function createNode(vnode) {let node; const {type} = vnode; If (typeof Type === "string") {// Native label node node = updateHostComponent(vNode); } else if (typeof type = = "function") {/ / function components again to differentiate the type of component and function component node = the prototype. IsReactComponent? updateClassComponent(vnode) : updateFunctionComponent(vnode); } else {// Text node node = updateTextComponent(vnode); } return node; Function updateHostComponent(vnode) {const {type, props} = vnode; const node = document.createElement(type); Console. log('document.createElement', node) // updateNode(node, props); // Attributes reconcileChildren(node, props. Children); // Traverses the children Return node; Function updateNode(node, nextVal) {object.keys (nextVal).filter((k) => k! = = "children") / / filter the children. The forEach ((k) = > (node = nextVal [k] [k])); Function updateTextComponent(vNode) {const node = document.createTextNode(vnode); const node = document.createTextNode(vnode); return node; Function updateFunctionComponent(vnode) {const {type, props} = vnode; // type is a function const vvnode = type(props); // vvnode->node const node = createNode(vvnode); return node; Function updateClassComponent(vnode) {const {type, props} = vnode; function updateClassComponent(vnode) {const {type, props} = vnode; // Class components need new const instance = new type(props); console.log('instance', instance); const vvnode = instance.render(); console.log('vvnode', vvnode); // vvnode->node const node = createNode(vvnode); return node; } // reconcileChildren(parentNode, children) { Const newChildren = array.isarray (children)? children : [children]; for (let i = 0; i < newChildren.length; i++) { let child = newChildren[i]; // vnode->node, node insert parentNode render(child, parentNode); } } export default { render };Copy the code

Create a SRC /myreact/ component.js file:

// Class components must derive from Component or PureComponent function Component(props) {// We need to bind this. } / / made a kind of Component tag Component. The prototype. IsReactComponent = {}; export default Component;Copy the code

Oh, don’t forget to change the contents of the SRC /index.js file:

// import React from 'react'; // import ReactDOM from 'react-dom'; import ReactDOM from './myreact/react-dom'; import Component from "./myreact/Component"; import './index.css'; // import App from './App'; import reportWebVitals from './reportWebVitals'; Class ClassComponent extends Component {render() {return (<div> <p> class Component -{this.props. Name}</p> </div>); } } export default ClassComponent; Function FunctionComponent(props) {return (<div> <p> function component -{props. Name}</p> </div>); } const jsx = ( <div className="myjsx"> <h1>111111</h1> <h2>222222</h2> <h3>111111</h3> <a Href ="https://www.baidu.com/"> </a> <FunctionComponent name=" FunctionComponent name "/> <ClassComponent name=" ClassComponent name" /> </div>) // Native tag // text node // function component // class component reactdom.render (JSX, document.getelementById ('root')); // console.log("version", React.version); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();Copy the code

The whole code is like this, the specific process is not detailed here, we have a good taste of the code, you can contact me if you have questions.

summary

In React17, React automatically replaces JSX with JS objects. 2. The JS object is vDOM, which can completely describe the DOM structure. Reactdom.render (vdom, container) converts vDOM to DOM and appends to container. 4. In fact, the transformation process goes through a diff process.Copy the code