Object.entries.map 渲染 React 组件数组

xen*_*ics 3 reactjs redux

我正在开发一个 React 网络应用程序。到目前为止,我总是将数据存储在数组中,如下所示:

areas: [
    { id: 0, title: 'Some title', isSelected: false }
]
Run Code Online (Sandbox Code Playgroud)

然后我就可以做

this.state.areas.map(x => <Component key={x.id} ... />
Run Code Online (Sandbox Code Playgroud)

然而,在浏览完 Redux 文档之后,我发现一个优点是存储数据,如下所示:

areas: {
  'some title': { id: 0, isSelected: false }
}
Run Code Online (Sandbox Code Playgroud)

这使得更新当前选定的区域变得非常容易

this.state.areas['some title].isSelected = true
Run Code Online (Sandbox Code Playgroud)

与通过 id 执行 .filter 然后更新isSelected.

但是,使用对象键而不是数组存储意味着我必须编写:

 { 
   Object.entries(this.props.areas).map(([k, v]) => {
     return <Component key={k.id} ... />
   })
 }
Run Code Online (Sandbox Code Playgroud)

可读性差了很多,而且打字也多了很多。

所以我的问题是:

  1. 有没有比Object.entries...实现我正在做的事情更好的方法?或者,还有更好的方法?
  2. 我应该首先使用数组吗?

谢谢。

小智 5

从您的问题来看,您似乎对何时将值存储在数组中以及何时将值存储为反应状态的对象感到困惑。这取决于您的要求。

  • 如果数据仅用于显示目的并且不会使用任何事件更改,则存储在数组中。例如,在选择框中呈现动态选项。您可以将值存储为数组,并可以使用“Array.map”创建组件数组并渲染它。

  • 当您更改事件数据/更新数据时,通常会使用对象。当涉及到更新其中的特定值时,对象很方便。例如,您正在渲染第一列中带有复选框的表行,并且在复选框标记/取消标记上您需要更新相关的行数据属性。

如果您的应用程序需要同时实现这两件事,您应该执行以下操作,

{
    areas: ['areaid_0', 'areaid_1', 'areaid_2'],
    areaDetails: {
        'areaid_0': {title: 'Some title', isSelected: false},
        'areaid_1': {title: 'Some title', isSelected: false},
        'areaid_2': {title: 'Some title', isSelected: false}
    }
}
Run Code Online (Sandbox Code Playgroud)

当谈到渲染时,你可以这样做,

this.state.areas.map(x => {
  const areaDetail = this.state.areaDetails[x];
  <Component key={x} {...areaDetail}... />
})
Run Code Online (Sandbox Code Playgroud)

当你想更新任何对象时,你可以这样做,

this.state.areaDetails[x].isSelected = true;
Run Code Online (Sandbox Code Playgroud)

希望这会对您有所帮助。


Rob*_*ise 5

Redux 文档经常推荐将对象存储在像这样的“ID 映射”中。请注意,按照惯例,键是IDs,而不是像 那样的任意属性title

虽然您确实可以使用Object.entries已演示的样式,但您几乎总是希望有某种逻辑排序顺序。

您不应该依赖 JavaScript 保留键的排序顺序,因此,自动转换为这种标准化结构的正常化库(Abramov 推荐的)等库也将返回result保留排序顺序的 ID 数组。参考这里

Redux 中的“标准化状态形状”文档还明确建议您依赖 ID 数组来进行排序:

  • 对单个项目的任何引用都应通过存储项目的 ID 来完成。
  • ID 数组应该用于指示顺序。

您的状态形状可能如下所示:

{
  areas: {1: {id: 1, title: 'some title'}, 2: {id: 2, title: 'other title'}},
  areaIds: [1, 2],
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以像这样迭代:

areaIds.map(id => <Component key={id} area={areas[id]} />)
Run Code Online (Sandbox Code Playgroud)

如果您确实想这样做Object.entries,您可以使用类似的库lodash,它可以让您简单地执行以下操作:

_.map(areas, area => <Component key={area.id} area={area} />)
Run Code Online (Sandbox Code Playgroud)