Skip to content

09.getDeriveStateFromProps源码实现

代码演化请观看视频,这里呈现相关代码:

js
// Component.js
export class Component {
    static IS_CLASS_COMPONENT = true
    constructor(props){
        this.updater = new Updater(this)
        this.state = {}
        this.props = props
    }
    setState(partialState){
        // // 1.合并属性
        // this.state = {...this.state, ...partialState}
        // // 2.重新渲染进行更新
        // this.update()
        this.updater.addState(partialState)
    }
    update(){
        // 1. 获取重新执行render函数后的虚拟DOM 新虚拟DOM
        // 2. 根据新虚拟DOM生成新的真实DOM
        // 3. 将真实DOM挂载到页面上
        let oldVNode = this.oldVNode; // TODO: 让类组件拥有一个oldVNode属性保存类组件实例对应的的虚拟DOM
        let oldDOM = findDomByVNode(oldVNode) // TODO: 将真实DOM保存到对应的虚拟DOM上  
        if (this.constructor.getDerivedStateFromProps) {///
            let newState = this.constructor.getDerivedStateFromProps(this.props, this.state) || {};///
            this.state = { ...this.state, ...newState };///
        }///
        let newVNode = this.render()
        updateDomTree(oldVNode, newVNode, oldDOM)
        this.oldVNode = newVNode
        if (this.componentDidUpdate) {
            this.componentDidUpdate(this.props, this.state);
        }
    }
}
js
function getDomByClassComponent(VNode){
    let { type, props, ref } = VNode
    let instance = new type(props)
    let renderVNode = instance.render()
    instance.oldVNode = renderVNode
    VNode.classInstance = instance ///
    ref && (ref.current = instance)
    // TODO: 需要删除的代码 start
    // setTimeout(()=>{
    //     instance.setState({xxx: '999999999999'})
    // }, 3000)
    // TODO: 需要删除的代码 end
    if(!renderVNode) return null
    let dom = createDOM(renderVNode);
    if (instance.componentDidMount) instance.componentDidMount();
    return dom
}

基于 VitePress 构建