useMemo和useCallback都会在组件第一次渲染的时候执行
之后会在其依赖的变量发生改变时再次执行
useMemo返回缓存的变量,useCallback返回缓存的函数
多个state改变会重渲染多此,借助useMemo可以在指定state改变时才执行对应的方法
1 | function expensive(){} |
useCallback返回的是缓存的函数
- 将我们传递给它的函数fnB返回,并且将这个结果缓存;当依赖a变更时,会返回新的函数。
- 既然返回的是函数,我们无法很好的判断返回的函数是否变更,
- 所以我们可以借助ES6新增的数据类型Set来判断如果存在父子组件,如果父更新,子也会更新,可以把useCallback返回的函数传给子props,这样就缓存不更新
1
const fnA = useCallback(fnB, [a])
等返回的函数更新后字才会更新
所有依赖本地状态或props来创建函数,需要使用到缓存函数的地方,都是useCallback的应用场景
useEffect、useMemo、useCallback都是自带闭包的。也就是说,每一次组件的渲染,其都会捕获当前组件函数上下文中的状态(state, props),所以每一次这三种hooks的执行,反映的也都是当前的状态,你无法使用它们来捕获上一次的状态。对于这种情况,我们应该使用ref来访问
类组件的shouldComponentUpdate和 PureComponent,为了减少重新 render 的次数,主要是减少父组件更新而子组件也更新的情况
React.memo是对标类组件PureComponent
子组件如果在 props 没有变化的情况下,就算父组件重新渲染了,子组件也不应该渲染
React.memo其实是一个高阶函数,传递一个组件进去,返回一个可以记忆的组件
如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。
1 | function myComponent(props) { |
一个组件重新重新渲染,一般三种情况:
- 要么是组件自己的状态改变
- 要么是父组件重新渲染,导致子组件重新渲染,但是父组件的 props 没有改版
- 要么是父组件重新渲染,导致子组件重新渲染,但是父组件传递的 props 改变
React 的性能优化方向主要是两个:
- 一个是减少重新 render 的次数(或者说减少不必要的渲染),
- 另一个是减少计算的量