首页 > 解决方案 > Redux 按索引读取数组元素

问题描述

我有一个存储在 redux 中的 post 对象数组。我正在映射帖子,并将 ID 和索引传递给 Post 组件:

posts.map((post, index) => {
  <Post id={post.id} index={index} />
});

redux 风格指南指出:

更喜欢让更多 UI 组件订阅 Redux 存储并以更精细的级别读取数据......

例如,不只是连接一个<UserList>组件并读取整个用户数组,而是<UserList>检索所有用户 ID 的列表,将列表项呈现为<UserListItem userId={userId}>,并已<UserListItem>连接并从存储中提取其自己的用户条目。

但是,我没有 postId 列表,但我仍在尝试通过映射帖子并传递对帖子组件的引用而不是帖子本身来订阅更多组件。(这是一个好主意吗?)

我的问题是关于我应该如何阅读商店的帖子。无论是按 ID 还是按索引:

  1. post = state.posts.find(post => post.id === props.id)
  2. post = state.posts[props.index]

显然,按索引读取会快得多。但是帖子数组可以重新排序。所以我想知道map函数创建的索引是否可靠?

标签: javascriptarraysreactjsobjectredux

解决方案


redux 风格指南只是一个风格指南。即使他们建议迭代一个 id 列表,如果你有一个组件列表,你也可以迭代它。

这里唯一的“问题”是您的应用程序可能会随着时间的推移变得越来越复杂,并且以后可能很难维护它。

如果您仍然想通过 id 查找帖子,该find方法很好,如果您的商店中没有数百件商品,应该不会有问题。

如果您想做第二种解决方案,您可以将您的减速器中的存储转换为如下所示:

  function reducer(action, state) {
    switch (action.type) {
      case 'YOUR_CASE': {
        return {
          ...state,
-         itemList: action.itemList,
+         itemList: Object.fromEntries(
+           action.itemList.map(item => ([item.id, item]))
+         ),
        }
      }
    }
  } 

然后,您的商店中将有一个这样的对象:

{
  1: {
    id: 1,
    title: 'some item',
  },
  2: {
    id: 2,
    title: 'some other item',
  },
}

注意这Object.fromEntries只是一个最近的 API,你可能想要填充它。

您当然需要itemList像这样更改之前用作数组的所有调用:

- itemList: state.itemList,
+ itemList: Object.values(state.itemList),

推荐阅读