【React系列】useEffect的第二个参数

1,099 阅读2分钟

setState 是 React 中最常用的命令,通常情况下,执行 setState 会触发 render。但是这里有个点值得关注,执行 setState 的时候一定会重新渲染吗?答案是不一定。当setState传入null的时候,并不会触发 render

只要父组件重新渲染了,即使传入子组件的props未发生变化,那么子组件也会重新渲染,进而触发render。React 组件渲染机制其实是一种较好的做法,很好地避免了在每一次状态更新之后,需要去手动执行重新渲染的相关操作。然而,带来方便的同时也会存在一些问题,当子组件过多或者组件的层级嵌套过深时,因为反反复复重新渲染状态没有改变的组件,可能会增加渲染时间又会影响用户体验,此时就需要对 React 的 render 进行优化。不必要的 render 会带来性能问题,因此我们的主要优化思路就是减少不必要的 render。

在 React 类组件中,可以利用shouldComponentUpdate或者PureComponent来减少因父组件更新而触发子组件的 render,从而达到目的。shouldComponentUpdate 来决定是否组件是否重新渲染,如果不希望组件重新渲染,返回 false 即可。React.memo是 React 16.6 新的一个 API,用来缓存组件的渲染,避免不必要的更新,其实也是一个高阶组件,与PureComponent十分类似,但不同的是,React.memo只能用于函数组件 。

useEffect 规则:

  • 在每次 render 之后执行

  • 接受第二个参数来控制跳过执行,下次 render 后如果指定的值没有变化就不会执行

  • useEffect 是在 render 之后浏览器已经渲染结束才执行

useEffect 参数的规则:

  • 可选的

  • 类型是一个数组

  • 值应该是 props 或 state

不同值的参数:

  • 不传参数

  • 空数组

  • 一个值的数组

  • 多个值的数组

  1. 不传参数:默认的行为,会每次 render 后都执行
useEffect(() => {
    console.log('useEffect with no dependency')
})
  1. 空数组:传入第二个参数,每次 render 后比较数组的值没变化,不会在执行,等同于类组件中的 componentDidMount
useEffect(() => {
    console.log('useEffect with empty dependency')
}, [])
  1. 一个值的数组:传入第二个参数,只有一个值,比较该值有变化就执行
useEffect(() => {
    console.log('useEffect widh specify dependency')
}, [id])
  1. 多个值的数组:传入第二个参数,有2个值的数组,会比较每一个值,有一个不相等就执行
useEffect(() => {
    console.log('useEffect widh specify dependency')
}, [id, name])