返回

React useSelector 仅在需要时触发更新的原理揭秘

前端

React 中的 useSelector 钩子提供了对 Redux 状态的访问,但在某些情况下,我们只希望在特定条件下触发组件更新。本文将深入探究 useSelector 内部机制,揭示其只在必要时触发更新的原理。

useSelector 如何工作

useSelector 接收一个选择器函数作为参数,该函数负责从 Redux 状态中提取所需的数据。当 Redux 状态发生变化时,Redux 会通知 useSelector 钩子,后者会重新运行选择器函数,并将其结果与前一次运行的结果进行比较。如果结果不同,则组件将重新渲染。

然而,并非所有 Redux 状态的变化都会导致 useSelector 重新运行选择器函数。只有当选择器函数依赖的状态发生变化时,才会触发重新运行。这可以通过以下方式实现:

React.memo

useSelector 钩子使用 React.memo 函数包裹选择器函数。React.memo 接受一个函数作为参数,并返回一个被记忆的函数。这意味着被记忆的函数只会重新运行,当其输入发生变化时。

因此,useSelector 仅在选择器函数的输入(即 Redux 状态中被选择的部分)发生变化时才会重新运行选择器函数。

用例

假设我们有一个组件,它从 Redux 状态中获取用户列表:

const UserList = () => {
  const users = useSelector((state) => state.users);
  return (
    <ul>
      {users.map((user) => <li key={user.id}>{user.name}</li>)}
    </ul>
  );
};

只有当 state.users 发生变化时,useSelector 才会在 UserList 组件中重新运行选择器函数。如果 state.otherData 发生变化,useSelector 将不会重新运行选择器函数,因为 UserList 组件不依赖于 state.otherData

局限性

虽然 useSelector 能够仅在必要时触发更新,但需要注意,它仍然是一个非惰性钩子。这意味着,无论组件是否实际使用 Redux 状态,useSelector 都会在每次 Redux 状态更新时运行选择器函数。

为了解决此问题,可以使用 useSelectorWithStore 钩子,它允许您指定要从中获取数据的特定 Redux store。这样,只有当指定的 store 发生变化时,才会重新运行选择器函数。

总结

useSelector 钩子利用 React.memo 函数,仅在选择器函数依赖的状态发生变化时才会重新运行选择器函数。这使得组件能够仅在需要时触发更新,从而提高性能。通过理解 useSelector 的内部机制,开发人员可以优化其 React 应用程序并确保高效的状态管理。