如何使用React Redux单独连接数组的每个元素

5

目前的做法是将整个书籍列表连接到书籍列表组件中。然而,通过仅更改状态中的几个字段来渲染大型组件并不是一种有效的方法。我不知道如何将每个书籍组件映射到各自的书籍状态

该项目正在使用redux。应用程序全局状态如下:

{
  "books": [
    {
      "field1": "field1",
      "field2": "field2",
      "field3": "field3",
    } ...
  ]
}

在图书列表组件中,我们使用React Redux将列表与其连接。
export default connect(state => ({
  books: state.books
}))(BookListComponent);

现在需求有所变化,书籍中的字段不会经常更改。问题是,如果修改一个字段,将会更新整个BookListComponent。这不是我期望的高性能组件。

我希望将连接逻辑下推到单个书籍组件中,以便使用reselect

状态中没有书籍的索引,我不知道如何编写连接以使其正常工作。

export default connect(state => ({
  books[index]: state.books[index]
}))(BookListComponent);

感谢您提前的支持,欢迎提供所有选项。

1
如果您使用key属性呈现书籍列表,则无需过多担心。您的项目将被跟踪并相应地更新。然后,您还可以为Book组件编写shouldComponentUpdate函数,以告诉何时不应重新呈现书籍。 - just-boris
3个回答

3

你的第二个例子是几乎正确的。可以声明一个带有两个参数的mapState函数,而不是一个参数。如果声明了两个参数,则Redux将使用传递给包装组件的props调用该mapState函数。因此,列表项的mapState函数应该是:

const mapState = (state, ownProps) => {
    const book = state.books[ownProps.index];
    return {book}
}

我的博客文章 Practical Redux, Part 6: Connected Lists, Forms, and Performance 展示了一些如何实现这一点的示例,并讨论了在Redux中实现应用程序性能的关键考虑因素。


但是在 reducer 中,您仍然必须返回一个新的数组,对吗?如果这个数组是嵌套的呢?比如 { books: [], CDs: [] } - Erez Cohen
如果您要更新嵌套数据,需要在更新时复制所有嵌套级别。请参阅Redux文档中的Immutable Update Patterns部分以获取示例。 - markerikson

0

您可以连接任何组件。没有硬性规定只能连接顶级组件。

虽然连接顶级组件并将props向下传递会有一定的性能损失,但我并没有看到它对性能产生明显的不利影响。在我看来,通过代码跟踪数据的好处总是值得的。这里有一个讨论链接


0

React 只更新变化的字段

虽然每次更新书籍时都会调用 render 函数,但这并不意味着整个列表都会重新渲染。

请记住,在 React 中我们使用的是虚拟 DOM。它允许我们仅更新实际更改的元素。

看一下这篇文章(它很短,并且在 codeopen 上有工作代码示例)https://facebook.github.io/react/docs/rendering-elements.html 以及这篇文章(稍微详细一些) https://facebook.github.io/react/docs/state-and-lifecycle.html

如果您已经阅读了这些文章,那么您只需要检查您的应用程序并查看每次更改时实际呈现的内容即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接