跳转至

React随记

1. React组件渲染顺序

React 组件更新的正常顺序,遵循 「父渲染 → 子渲染 → 子副作用 → 父副作用」 的规律:

  1. 当父组件的 layers 状态更新时,会触发父组件重新渲染
  2. 父组件重新渲染时,会将新的 layers 值传递给子组件
  3. 子组件接收到新的 props 后,会触发重新渲染
  4. 子组件渲染完成后,其 useEffect 会先执行(打印日志)
  5. 父组件等待所有子组件渲染完成后,其 useEffect 才会执行(打印日志)

像是一个栈,所以当父组件和子组件同时监听同一个变量时(子组件监听的是父组件通过props传进来的),子组件的useEffect会先执行,父组件的useEffect会后执行

2. React状态更新

  1. 当调用 setLayers(……) 时,React 不会立即更新 layers 状态
  2. React 会将这个更新请求放入一个队列中,等待当前函数执行完毕后,再批量处理这些更新

所以当使用setLayers更新状态后,立即打印状态值,会得到更新前的状态值,而不是更新后的最新值

3. 闭包问题

React中的useEffect和useCallback等hook函数中,如果使用了组件中的状态变量,那么这些变量会被捕获,形成闭包,导致变量值不会实时更新(只会记录创建或绑定时的状态值,之后如果状态变量发生修改,闭包中的变量值不会更新,仍旧是初始值)。

解决办法:使用依赖数组监听状态变量,当状态变量发生改变时,重新执行useEffect或useCallback中的函数,从而更新闭包中的变量值,这样就能保证闭包中的变量值是实时更新的。

4.useCallback

useCallback 是 React 提供的一个 hook,用于优化函数组件的性能。它接受一个函数和一个依赖数组作为参数,返回一个新的函数。当依赖数组中的值发生变化时,useCallback 会重新创建这个函数,否则会返回上一次创建的函数。

如果像定义函数一样在React组件中定义函数,或是普通变量,那么在组件每次更新时都会被重新初始化,使用useCallback可以将函数缓存起来,避免每次更新都重新创建函数,从而提高性能。只有当依赖数组中的值发生变化时,才会重新创建函数。(对于频繁更新的组件应该有较大的作用,而一般长时间都不会更新的组件中,使用普通函数定义的方式应该问题也不大)

5. React依赖数组

如果依赖数组中的数据是值类型,则判断时只需判断值是否相等,如果是引用类型,则判断地址是否相等。而useRef创建的ref对象本身的地址是固定不变的,所以放到依赖数组中是没有任何意义的。