使用 React.memo、useCallback 和 useReducer 进行 React 优化。
本文最初发表于codebushi.com
随着 React Hooks 的发布,我开始在 React 代码中使用越来越多的函数式组件。在阅读 React 文档时,我经常看到有人提到函数式组件useReducer比 React 更“高效” useState。我不明白为什么,于是深入研究了一下。经过大量的研究和实验,以下是我的发现。
不借助视频很难演示这些概念,但希望这些内容能让你理解。我建议使用 React 开发者工具,并Highlight Updates在设置中启用相关功能进行测试。另外,在子组件上添加 `console.log` 输出也很有帮助,如果看到控制台输出,则说明组件正在重新渲染。
===
我们的场景:一个父组件,其子组件接收来自父组件的 props。假设两者都是函数式组件,并且父组件使用某种机制useState来管理状态。
如果传递给子组件的 props 很简单,则应该使用 `react.memo` 包裹子组件,React.memo以防止 props 不变时重新渲染。`react.memo`React.memo会自动优化函数式组件,其作用类似于shouldComponentUpdate生命周期方法。了解更多关于React.memo 的信息。
如果父组件将一个函数(具体来说,是一个用于更新父组件状态的函数)传递给子组件,仅使用 `useCallback`React.memo是行不通的。父组件中的函数需要用 ` useCallbackuseCallback` 钩子函数包裹起来。这是因为每次父组件重新渲染时,该函数都会被“重新渲染”,因此子组件会始终将该函数视为一个新的 prop。了解更多关于`useCallback` 的信息。
如果useReducer父组件使用 hook 来管理状态,那么我们就无需担心 `useReducer`useCallback会useReducer返回一个dispatch可以传递给子组件的方法。该方法不会在父组件每次重新渲染时都被重新渲染。我确信这就是`useReducer` 比 `useReducer` 更高效的dispatch原因。阅读更多关于`useReducer` 的内容。useReduceruseState
在使用深度嵌套的子组件时,建议useReducer结合 React Context 使用 hook。你可以dispatch使用 Context 将方法向下传递,从而避免 props 传递过度。了解更多关于这种模式的信息。