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