一、react的渲染原理
简单来说: 1、从根节点(一般是app)开始,自上而下beginwork遍历组件(类似前序遍历),将每一个组件节点都生成一个对应的fiber对象(这个fiber对象包含了tag、key、ref、retutn、sibling、child、等等的属性),在beginwork的过程中,会形成一个fiber链表,将组件进行关联 2、在beginwork的过程中,遍历到每一个没有子组件的节点时,会进行completework工作,进行相应的dom节点的生成,同一层级的组价节点都completework后,会指向父级节点的fiber对象。如此循环直到最终挂在到根节点app(这个过程并不是单纯地先beginwork,再completework,而是交叉工作的)
二、react在虚拟dom的diff做了哪些优化
传统的虚拟dom的diff,在每一次渲染时,都要去完整地走一遍上述一的渲染过程,相当于每一次都要遍历所有节点。 但react做了优化,在completeWork的过程中,针对每一个fiber对象,都会生成一个对应的tag,而如果是需要重新渲染的,会打上effectTag标签,并且会存进一个effectList的单向链表。所以在重新渲染的过程中,只需要渲染effectList中的fiber节点就好了
三、react的双Fiber树渲染机制
其实在react的渲染过程中,是存在着两颗Fiber树的。 当前屏幕上显示内容对应的Fiber树称为current Fiber树 正在内存中构建的Fiber树称为workInProgress Fiber树 这两个树通过alternate进行关联
currentFiber.alternate === workInProgressFiber;
workInProgressFiber.alternate === currentFiber;
简单地来说,根节点app的current指针指向了哪棵树,哪棵树就是current Fiber,另外一棵就是workInProgress Fiber树。 之所以有双缓存渲染机制,这是因为假如只有一个Fiber树的话,那相当于每一次update,都要用一棵全新的Fiber树去替换当前的Fiber树。但是有两棵Fiber树的话,通过alternate 将两颗树进行关联,并且在生成workInProgressFiber树时,会去判断复用currentFiber的一些fiber节点,减少一些节点的构造,能减少渲染时间。
四、key的作用
体现在判断当前fiber节点的dom是否能复用 completeWork的过程中,判断一个fiber节点是否能复用的流程是: 判断是否有child->判断key值是否相同->判断type是否相同,全部相同的话,则当前fiber节点可复用。 假如在同级节点key值不唯一,会导致复用了其他节点相同key值的节点,就会渲染出相同的dom节点 假如用了index作为key值,会出现比如删除节点,设置新的节点,但由于index为key相同,还是复用了原来被删除的
五、JSX怎么理解
首先,JSX是react特有的表达式,因为它最终会被babel给转化成一个React.createElement组件对象,这个是react内置的对象,最特殊的,就是包含了一个属性$$typeof: REACT_ELEMENT_TYPE。而之所以会转化成React.createElement组件对象,是为了方便生成对应的fiber,JSX与Fiber节点保存的数据会进行对比,生成组件对应的Fiber节点,并根据对比结果为Fiber节点打上标记。
|