每次setState都会调用组件的render函数?
setState后会进入到shouldComponentUpdate钩子函数,由该函数的返回值决定是否调用render函数。
如果组件中包含有子组件那么render完之后会进入子组件的shouldComponentUpdate钩子函数。调用了render函数一定会重新渲染DOM?
调用了render函数并不意味着一定会重新渲染DOM。这里需要提到react的虚拟dom的概念(virtual DOM)。render函数调用并不会直接渲染成dom,而是,返回一个virtual DOM,何为virtual DOM?他其实就是一个js对象,这个对象描述了真实dom的各个属性。在真正渲染成为DOM之前,会执行react里的diff算法,比较原virtual DOM和新的virtual DOM(新旧两个对象)的差异,如果没有差异则不会重新渲染DOM,如果有差异只重新渲染差异的地方,这也是react高性能的原理。diff算法运行在哪个生命周期呢?
在render之后,render返回的是virtual DOM。diff算法就是对virtual DOM进行比较。从而以最优策略更新DOM。
我们刚才提到shouldComponentUpdate可以控制render函数是否调用,shouldComponentUpdate返回为false时不调用render。假如state和props并没有改变,那么调用render,执行diff运算就毫无意义。我们可以在shouldComponentUpdate钩子函数中比较state和props是否改变,如果没有改变直接返回false,不进行render调用。这时候react引入了PureComponent概念,他会在render之前对state和props进行浅比较,若state和props都相同,则不会调用render。这个浅比较是在shouldComponentUpdate中进行的,所以,使用PureComponent时不能在用shouldComponentUpdate钩子函数了,因为会覆盖默认的钩子函数行为。关于父子组件中,shouldComponentUpdate和render调用顺序:
父组件shouldComponentUpdate =》 父组件render =》子组件shouldComponentUpdate =》 子组件render ...浅比较决定是否调用render函数(PureCompoennt)
render返回virtual DOM,然后进行diff运算
diff运算决定怎么操作DOM
怎么测试是否渲染DOM?
操作时可以观测浏览器调试面板的元素节点是否有闪动,dom操作时即使值一样也会有闪动。PureComponen和React.Component区别
PureComponent在render之前会进行浅比较,React.Component不会。
当设置state和props的属性值为引用类型时要格外注意,使用PureComponent时很可能不会把新值渲染到DOM上,因为浅比较的机制根本就没调用 render。而React.Component不会浅比较,直接render,返回virtual DOM进行diff运算,从而更新DOM。合理的利用PureComponent可以提高性能,滥用则会拖慢性能。我认为,在state和props的属性值都为值类型时使用会提高性能。反之,为引用类型时,为保证DOM的渲染,通常会使用ES6的展开语法从而使引用类型的属性值不一样(展开语法是新建了一个对象,与原对象指针不相同),使浅对比总是返回false,从而调用render。请注意,这时使用PureComponent比直接使用React.Component多做了一件事——浅对比,这时会对性能拖累。
react的更新机制
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...