在列表中使用 react redux 钩子会影响性能吗?

Posted

技术标签:

【中文标题】在列表中使用 react redux 钩子会影响性能吗?【英文标题】:Does it hurt performance to use the react redux hooks in a list? 【发布时间】:2020-06-18 20:42:55 【问题描述】:

这个问题专门针对较新的 react redux 钩子,特别是 useSelector 和 useDispatch。假设您有一个组件是列表,另一个组件是列表项。列表组件包含列表项的列表。

您需要在列表项中使用一部分 redux 存储,并在列表项中调度一个操作。对于列表中的每个项目,您需要的来自 store 和 dispatch 函数的数据将是相同的。

您应该在项目本身中使用这些钩子还是使用父列表组件中的钩子并通过道具将存储和调度功能传递给项目?对列表中的每个项目执行 useDispatch 和 useSelector 挂钩是否会对性能产生一些影响?

编辑以添加代码示例:

const List = () => (
  <div>
      someArray.map((item) => 
        return (
          <ListItem/>
        );
      )
  </div>
);

const ListItem = () => 
  const myState = useSelector((state) => state);
  const dispatch = useDispatch();
  // Do these here or in the parent and pass down as props?


  return (
      <div />
  );
;

【问题讨论】:

这里有少量的上下文代码吗?这很难抽象地回答。简短的回答是“视情况而定”。 【参考方案1】:

在任何地方调用 useDispatch() 都不会出现性能问题,因为这不会导致组件重新渲染。

useSelector 的问题是哪些组件需要访问哪些数据,以及如果给定的数据位发生更改,哪些组件将重新呈现。

通常,组件应始终尝试选择它们呈现自身所需的最少状态量。

“选择父项中的所有数据”和“在父项中选择项目 ID,在子项中按 ID 选择项目”方法都是可行的。如果列表中的数据可能更新得比较频繁,您可能更喜欢在每个列表组件中按 ID 选择项目。

但是,如果父项也在任何单个项目发生更改时重新渲染,则强制所有列表项组件重新渲染,除非您主动优化它们(例如包装列表React.memo() 中的项目)。

理想情况下,更新列表中的一项不应导致父项重新呈现,或者它确实重新呈现并且子项被记忆,因此只有一个列表项实际上会重新呈现自身。

更多详情请看我的帖子:

Practical Redux, Part 6: Connected Lists and Performance A (Mostly) Complete Guide to React Rendering Behavior

【讨论】:

感谢您的回答,我了解重新渲染,我想我更多的是询问在每个项目中调用 useX 挂钩,而不是在父项中调用一次并传递结果/参考下。在我看来,如果它在列表项中完成,则该挂钩(函数)被调用并执行 n 次,而如果它在父项中完成,则它只被调用一次,然后将引用传递给每个子项/项。 根据我链接的文章,React-Redux 的性能就是确保在分派任何给定操作时需要渲染的组件更少。这通常需要 更多 组件从存储中读取 更小 位的状态。这确实增加了商店订阅和正在运行的mapState 函数的数量,但它们通常运行得相当快,并且更多订阅回调的成本低于使用可能“浪费”的渲染重新渲染更多组件的成本.

以上是关于在列表中使用 react redux 钩子会影响性能吗?的主要内容,如果未能解决你的问题,请参考以下文章

在组件外部使用 redux 钩子来实现代码的可重用性

如何使用 react-redux 钩子测试组件?

无效的挂钩调用。钩子只能在反应函数组件内部使用...... useEffect,redux

如何正确使用带有 react-redux 的 useSelector 钩子的 curried 选择器函数?

在 React 中,如何在所有组件中拥有一个自定义钩子实例?

React:我想提交一个表单并想通过钩子(useSelector和useDispatch)将数据保存在redux store中