React的渲染流程
React的渲染流程
- 在render函数中返回jsx, jsx会创建出
ReactElement对象(通过React.createElement的函数创建出来的) ReactElement最终会形成一棵树结构, 这棵树结构就是vDOM- React会根据这样的vDOM渲染出真实DOM
React的更新流程
React更新流程
- props/state发生改变
- render函数重新执行
- 产生新的DOM树结构
- 新旧DOM树 进行diff算法
- 计算出差异进行更新
- 最后更新到真实DOM
什么是diff算法? diff算法并非React独家首创,但是React针对diff算法做了自己的优化,使得时间复杂度优化成了O(n) 对比两颗树结构,然后帮助我们计算出vDOM中真正变化的部分,并只针对该部分进行实际的DOM操作,而非渲染整个页面,从而保证了每次操作后页面的高效渲染。
-
React在props或state发生改变时,会调用React的render方法,会创建一颗不同的树
-
React需要基于这两颗不同的树之间的差别来判断如何有效的更新UI
-
如果一棵树参考另外一棵树进行完全比较更新,那么即使是最先进的算法,该算法的复杂程度为 O(n³) ,其中 n 是树中元素的数量
-
如果在 React 中使用了该算法,那么展示 1000 个元素所需要执行的计算量将在十亿的量级范围
-
这个开销太过昂贵了,于是,React对这个算法进行了优化,将其优化成了O(n)
-
同层节点之间相互比较,不会跨节点比较(一旦某个节点不同,那么包括其后代节点都会被替换)
-
不同类型的节点,产生不同的树结构(当根节点为不同类型的元素时,React 会拆卸原有的树并且建立起新的树)
-
开发中,可以通过key属性标识哪些子元素在不同的渲染中可能是不变的
-
-
在遍历列表时,总是会提示一个警告,让我们加入一个key属性,当子元素拥有 key 时,React 使用 key 来匹配原有树上的子元素以及最新树上的子元素。
- 在最后位置插入数据 -- 这种情况,有无key意义并不大
- 在前面插入数据 -- 这种做法,在没有key的情况下,所有的li都需要进行修改
- 在中间插入元素 -- 新增2014, key为2016元素仅仅进行位移,不需要进行任何的修改
<ul> <li key="2015">Duke</li> <li key="2016">Villanova</li> </ul> <ul> <li key="2015">Duke</li> <li key="2014">Connecticut</li> <li key="2016">Villanova</li> </ul> -
key的注意事项:
- key应该是唯一的;
- key不要使用随机数(随机数在下一次render时,会重新生成一个数字);
- 使用index作为key,对性能是没有优化的;