React源码解析6-类组件的更新

1.路口方法

beginWork()

判断组件更新是否可以优化

根据节点类型分发处理不同更新逻辑

根据expirationTime等信息判断节点是否可以跳过

2.tag判断不同方法

1.函数组件

直接传入props 拿到children的jsx 转成React.createElement元素 再去调用reconcileChildren

reconcileChildren

1.根据props.children生成fiber子树

2.判断fiber对象是否可复用

3.列表根据key优化

3.一般组件更新流程

image-20210507094249300

4.class组件的更新

image-20210507095834156

1.在mountIntance时候会执行willMount

2.组件刚开始挂载时候是采用子组件先挂载原则的 我们创建时候只会创建instance 不会创建current(组件的fiber) 我们判断父组件有没有current来执行子组件是挂载还是更新,这样的顺序 父先有instance 子有instance和fiber 子挂载有current 父挂载有current的顺序。

3.挂载之后(这时候已经有页面啦)再去执行didmount 这个生命周期 如果有setstate则会触发更新 创建一个update payload设为新的state 加入到这个class的fiber queue中 如果有多个update 那么会在updateQueue中以basestate:{number:0} 然后firstUpdate->secondUpdate形式存放

然后走到schdulework 然后找到root优先级最高的去执行更新 走到requestwork 发现还在rendering(因为在didmont时候就是还在render(挂载)阶段 这时候直接返回)

等挂载阶段完成后 会在commit lifeCycle时候去执行schdulework 然后performSyncwork 然后执行updateClasssComponent带上updateQueue 当作一次更新啦

4.5.生命周期的更新流程

image-20210507113502388

5.生命周期因为一开始在render阶段所以会先收集state 而不是立即去执行performwork 事件触发一开始batch阶段 所以一开始也不会执行performwork

都是先加到queue中

都是后面再来执行performwork去更新class组件 执行updateQueue中的所有queue

6.异步函数修改state都是一开始只会把回调函数记录到callback中 ,先同步代码执行完更新完视图(步骤和之前一样) 后面再去执行异步 异步代码加入会修改state 再进入requestwork来更新state 此时不是batch状态啦 只有直接在事件函数里面的才是batch 这个时候就直接performSyncwork更新视图

所以异步函数里面都是一个setstate走一次performwork 有一个updateQueue 有一个baseState 而不会两个setState连在一个queue中共享一个baseState.

handleClick=(e)=>{
    //baseState都是一样的 他们是同一个updateQueue更新
    this.setState({number:this.state.number+1})
     this.setState({number:this.state.number+1})
     //下面的setTimeout 不走batch 所以就是多个performwork 多个updateQueue 多个baseState 
     setTimeout(()=>{
       this.setState({
         number:this.state.number+1
       })
       console.log('state',this.state.number);
       this.setState({
         number:this.state.number+1
       })
       console.log('state',this.state.number);
     },1000)
  }
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享