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