think
think copied to clipboard
React源码(v15.0.3)解读-收获
跟随着《深入React技术栈》一书,对React v15.0.3的源码进行了简单的解读,以下是部分读书笔记:
1、mountComponent本质上是递归渲染内容的,所以,由于递归的特性,父组件的componentWillMount要先于子组件的componentWillMount执行,而父组件的componentDidMount则在其子组件之后调用。
2、在componentWillReceiveProps中调用setState时,不会触发re-render,此时只是把state合并到更新队列里边去。
3、在componentWillReceiveProps、shouldComponentUpdate和componentWillUpdate中也无法获取到更新后的state值,此时state仍然在更新队列里边,需要执行了inst.state = nextState之后才能访问到,也即只有在render和componentDidUpdate之后this.state获取到的才是更新之后的state。
4、updateComponent本质上也是递归渲染内容的,由于递归的特性,所以父组件的componentWillUpdate是在子组件的componentWillUpdate前调用,父组件的componentDidUpdate则是在子组件的componentDidUpdate之后调用。
5、在shouldComponentUpdate和componentWillUpdate中禁止调用setState方法,这会导致组件渲染的死循环。
6、如果在shouldComponentUpdate和componentWillUpdate中调用setState方法,由于setState方法中会调用performUpdateIfNecessary判断是否需要更新,performUpdateIfNecessary则会判断此时的更新队列是否为空(this._pendingStateQueue != null),不为空则调用updateComponent方法进行更新,而updateComponent方法又会调用shouldComponentUpdate和componentWillUpdate方法,造成循环调用,形成死循环。
7、事务就是将需要执行的方法使用wrapper封装起来,再通过事务提供的perform方法执行,而在perform执行之前,先执行所有wrapper中的initialize方法,执行完perform之后,再执行wrapper提供的close方法。一组initialize和close方法称为一个wrapper。多个wrapper可以嵌套叠加。
8、React将Virtual DOM树转换成actual DOM树的最少操作过程称为调和(reconciler)。diff算法便是调和的具体实现。
9、diff策略
- 策略1:Web UI中跨层级的DOM操作很少,可以忽略不计。(tree diff)
- 策略2:拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。(Component diff)
- 同一类型的组件,继续按照原策略继续比较Virtual DOM树。
- 不同类型的组件,将该组件判断为dirty component,然后替换掉整个组件下的所有节点。
- 对于同一类型的组件,可能其Virtual DOM没有任何变化,如果确切知道这一点,React允许用户通过shouldComponentUpdate来判断该组件是否需要进行diff分析。
- 策略3:对于同一层级的一组节点,可以通过唯一id来进行区分。(element diff)
- INSERT_MARKUP(插入操作),插入全新的节点到集合中
- MOVE_EXISTING(移动操作),旧集合中有新组件类型,且element可更新,DOM节点可以复用,则进行移动操作。
- REMOVE_NODE(删除操作),旧的组件类型,新集合里也有,但element不能复用和更新,或者旧组件不在新集合里,则进行删除操作。
10、针对跨层级操作忽略不计现象,React使用updateDepth来进行层级控制。只对拥有相同层级的树的DOM节点进行比较,当发现节点不存在时,则该节点以及其子节点都应该被完全删除,不用于进一步的比较。
11、当出现跨层级移动时,React不会移动节点,而是把节点对应的整棵树删除后重新创建。这会影响性能,因此官方建议不要进行DOM节点的跨层级操作。
12、开发组件时,保持稳定的DOM结构有助于提升性能,例如可以用css来控制元素的显示和隐藏,而不是添加和删除。
13、尽量减少将最后一个节点移动到列表首部的操作,否则当节点过多或更新频繁时,会一定程度上影响渲染性能。
14、React patch就是将react diff计算出来的DOM树结构差异队列更新到真实的DOM上去,最终让浏览器得以渲染更新的数据。