react高级知识


一、React Hook要解决的问题

1.可以在函数组件中使用state和生命周期
2.解决state变更逻辑的可复用 3.解决class组件一个业务逻辑分散在不同生命周期,一个生命周期包含不同业务逻辑的问题   二、React性能优化关键点 减少render方法的调用,在shouldComponentUpdate里判断props或state是否发生了改变,或者继承自PureComponent 保持稳定的dom结构,尽量避免dom节点跨层级移动操作 使用css来隐藏节点,而不是真的移除或添加DOM节点 如果有多个子或孙组件需要使用同一个state,此时应使用redux,而不是将公共的state移到祖先组件中,否则组件层次太深的话,在祖先组件setState会导致无数个子孙组件的render方法再次被调用  react性能优化实战   三、ReactDom Diff算法 算法实现
另一篇 若采用常规的树比较方法,时间复杂度是O(n^3),React基于一些假设,将时间复杂度变为O(n),相应的策略有: 1. 对两颗vdom树,采用逐层比较策略

不存在跨层级的节点移动,因此节点间只存在添加、删除操作。如下图所示,当想把A移动到D下面时,先删除A,然后再到D节点中创建A

2. 两个不同类型的元素,生成的树肯定是不同的,当某一层级两个元素的类型不同,就直接生成该节点及子树,没有必要再递归比较了。如下图:当component D换成了component G 后,即使两者的结构非常类似,也会将D删除再重新创建G 3.对于同一层级的一组子节点,通过指定唯一的key进行区分。通过key可以准确地发现新旧集合中的节点是否只存在位置不同的情况,若是,只需要将旧集合中节点的位置进行移动,更新为新集合中节点的位置即可,无需进行节点删除和插入。   基于key的移动算法策略: 如果当前节点在新集合中的位置比老集合中的位置靠前的话,是不会影响后续节点操作的,因此不进行位置移动(例如下图中的B和d):      

diff过程如下:

    使用一个变量(下面假设为lastIndex)来记录在新集合访问过的节点中,其在老集合的最大下标,那么需要移动的节点,就应该移动到该位置,初始值为0。

    循环新集合

  • 节点B:  lastIndex=0,   oldIndex=1; lastIndex < oldindex,因此B节点不动,lastIndex= Math.max(oldIndex, lastIndex) = 1
  • 节点A:lastIndex=1, oldIndex=0;lastIndex > oldIndex,因此A节点进行移动操作,lastIndex= Math.max(oldIndex, lastIndex) = 1
  • 节点D:lastIndex=1,   oldIndex=3;lastIndex < oldindex,因此D节点不动,lastIndex= Math.max(oldIndex, lastIndex) = 3
  • 节点C:lastIndex=3,   oldIndex=2;lastIndex > oldindex ,因此C节点进行移动操作。循环结束

四、渲染原理

渲染原理

五、组件懒加载

React.lazy方法可以异步加载组件文件。

const Foo = React.lazy(() => import('../componets/Foo));

React.lazy不能单独使用,需要配合React.suspense,suspence是用来包裹异步组件,添加loading效果等。

loading...
}>