• 每次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多做了一件事——浅对比,这时会对性能拖累。