Train of thought

At first, with no reference at all, I thought to myself, “How do I implement the React component?” IT was a bit confusing. Let’s start with a simpler functional component: Try rendering a functional component using the render we did earlier:

function Dinner(props) {
    return <div>
        <h1>
            welcome to my restaurant
        </h1>
        <p>
            dinner has {props.menu}
        </p>
    </div>
}

const el = <Dinner menu="chicken, fish and fruits" />

React.render(el, document.getElementById("root"));
Copy the code

After NPM run start, we can see the console error and print messages. The current render implementation does not parse the component:

Function component

Based on the console information, we can see that when we pass in the function component, the vDom tag changes from a string to a function, which is our custom function component, and attrs is the props we are passing in. So change createElement from returning only tag, attrs, and children to a tag that accepts a function type, and run attrs as an argument.

function createElement(tag, attrs = {}, ... children) { if (typeof tag === 'function') { return tag(attrs); } return {tag, attrs, children; Operator}; }Copy the code

Then after NPM run start, open the page and find that our custom component appears

Class components

Class components are usually defined using Class MyComponent extends React.Component. Then you can use react setState, lifecycle, etc.

class Page extends React.MyComponent { constructor(props) { super(props); this.state = { temperature: 28, }; } render() { const { temperature } = this.state; Return (<div> today is {temperature} degrees <br /> <button onClick={() => {this.setState({temperature: this.state.temperature + 1, }); }}> Add one degree! </button> </div> ) } }Copy the code

So we should define our base class like react.component.react class components that inherit from this base class.

Constructor (props) {this.isreactComponent = true; // Class MyComponent {constructor(props) {this.isreactComponent = true; this.state = {}; this.props = props; } setState(changedState) { const {... oldState} = this.state; Object.assign(this.state, changedState); // setState triggers rerendering this.render(this, this.container); }}Copy the code

When the class component createElement is essentially a function, it needs to be initialized with its own render function, which prints the following:

Since we in the mountComponent need to determine if the vDom is a class component, the class component needs to return its own render() content as the rendered virtual DOM. The isReactComponent in MyComponent helps us determine.

if (vDom.isReactComponent) {
    const _tempDom = vDom;
    _tempDom._container = container;
    vDom = _tempDom.render();
}
Copy the code

Then run the top one and find the render successful

But the problem is: clicking “add one degree” does not trigger the rendering again after the state change. The rendering again requires the container attribute of the previous rendering, so we put container in again

class MyComponent { constructor(props) { this.isReactComponent = true; this.state = {}; this.props = props; } setState(changedState) { Object.assign(this.state, changedState); // setState triggers rerender render(this, this._container); }} function render(vDom, container) {console.log("render start"); container.innerHTML = ""; container && container.appendChild(mountComponent(vDom, container)); console.log("render end"); }Copy the code

Finally try and find success!

conclusion

The React component is divided into function components and class components. When the function component is initialized, it needs to execute the function with props as an argument. The return content is the virtual DOM to render. Class components have their own render() content, so initialize the component to distinguish, then call the class component’s own constructor, and render() the actual result of class component render()! The discussion of state and PROPS changes, and related lifecycles, will then begin. PS: The code posted will change with the update, and there may be some problems. When the whole series is over, we will post the complete code ^ ^. If there is any question, I refer to some results on the Internet, but I hope I can understand react~ through this process