在上一篇文章的基础上添加处理类组件渲染。
1、改造index.js,实现一个类组件
// index.jsimport React from './react';import ReactDOM from './react-dom';class Counter extends React.Component {constructor(props) {super(props)this.state = { number: 0, name: this.props.name }}handleClick = () => {this.setState({number: this.state.number + 1})}render() {return (<div>{this.state.name}<div>{this.state.number}</div><button onClick={this.handleClick}>增加</button></div>)}}ReactDOM.render(<Counter name="计算器" />, document.getElementById('root'));
2、实现类组件继承的Component父类
// Component.jsimport { createDom } from './react-dom'class Component {static isReactComponent = true // 标记类组件constructor(props) {this.props = propsthis.state = {}}render() {throw new Error("此方法为抽象方法,需要子类实现")}}export default Component
3、将Component放在react对象上
// react.jsimport Component from "./Component";const React = { createElement, Component }
4、类组件挂载逻辑处理
4.1 根据类组件标记判断是否为类组件

4.2 mountClassComponent方法处理
/*** 挂载类组件* @param {*} vdom 类组件虚拟dom*/function mountClassComponent(vdom) {const { type, props } = vdom// 创建类的实例const classInstance = new type(props)// 调用render方法,返回要渲染的虚拟dom对象const renderVdom = classInstance.render()// 根据虚拟dom创建真实dom对象const dom = createDom(renderVdom)// 为以后类组件更新做准备,把真实dom挂载到实例上classInstance.dom = domreturn dom}
5、类组件更新逻辑处理
5.1 更新方法setState实现
// Component.jssetState(partialState) {const state = this.state// 新的state和旧的state合并this.state = { ...state, ...partialState };const newVdom = this.render()updateClassComponent(this, newVdom)}function updateClassComponent(classInstance, newVdom) {const oldDom = classInstance.dom // 取出类组件上次渲染出来的真实dom// 创建新的DOMconst newDom = createDom(newVdom)// 新的替换老的oldDom.parentNode.replaceChild(newDom, oldDom)classInstance.dom = newDom}
5.2 更新新的dom
react-dom.js文件updateProps方法增加对属性方法的判断
6、实现效果

7、源代码
本文地址:https://gitee.com/linhexs/react-write/tree/3.react-ClassComponent-render/
