从shouldComponentUpdate看React性能优化

676 阅读2分钟

先来看个问题:当组件改变(状态、属性或其他)时,其子组件会重新渲染吗?

解答过程:这里需要分三种情况

一、当组件的props改变时

image.png 在官网中可以看到,一个组件就像是一个函数,接受props作为参数,返回一个新的组件以更新UI,所以当父组件的属性改变时,会调用render函数

二、当组件的state改变时

state和props类似,只是state是由组件内部控制的,当state更新时,也会触发render,更新UI

三、当组件有其他改变时

const Text = () => {
  const handleClick = () => {
    console.log('点击');
  }
  return(
   <div>
     <div onClick={() => handleClick}>点击</div>
     <TextOne />
   </div>
 )
}

在这种情况下,就不会触发TextOne组件的更新,因为没有触发state和props的变化

接下来的问题是:每次父组件的props或state变化时,都会调用render函数,那么子组件也会重新创建吗?

image.png 根据文档可知,render只是生成一棵新树,与旧树做对比。在对比的过程中,使用diff算法

在diff算法中,当元素的根结点变化时,比如从<a></a>变为<div></div>,组件会卸载并重新创建。

如果diff检测到元素没变,但是属性变化,那组件实例就不会卸载,只会更新

所以现在可以明确的是,在父组件的状态改变时,子组件也会重新render,在render当时候就会生成一个新的树,之后采用diff算法来决定是否更新

虽然React会做diff算法,但是每次都render也会有性能消耗。所以接下来的方向就是如何减少子组件render的次数

React提供了几种控制render的方法 PureComponent / shouldComponentUpdate /useMemo 当使用这些方法时,可以根据PreProps或PreState来自行决定什么时候去Render