Object.entries.map用于渲染反应组件数组

时间:2017-09-13 01:32:28

标签: reactjs redux

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

areas: [
    { id: 0, title: 'Some title', isSelected: false }
]

然后我就可以了

this.state.areas.map(x => <Component key={x.id} ... />

然而,在浏览Redux文档之后,我发现存储数据的优点如下:

areas: {
  'some title': { id: 0, isSelected: false }
}

通过执行

,可以非常轻松地更新当前选定的区域
this.state.areas['some title].isSelected = true

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

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

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

可读性差得多,打字也多。

所以我的问题是:

  1. 有没有比Object.entries...更好的方式来实现我的目标?或者有更好的方法吗?
  2. 我应该首先使用数组吗?
  3. 感谢。

2 个答案:

答案 0 :(得分:4)

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

  • 存储在数组中,如果数据仅用于显示目的而不会使用任何事件进行更改。比如,在选择框中渲染动态选项。您可以将值存储为数组,并可以使用“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}
    }
}

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

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

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

this.state.areaDetails[x].isSelected = true;

希望,这对你有所帮助。

答案 1 :(得分:4)

将对象存储在某种“ID地图”中,这通常是recommended by the Redux docs。请注意,按照惯例,键是ID,而不是像title这样的任意属性。

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

您不应该依赖JavaScript保留键的排序顺序,因此,normalizr(Abramov推荐)等自动转换为此规范化结构的库也将返回result数组将保留排序顺序的ID。 Reference Here

Redux的“规范化状态形状”文档还明确建议您依赖一系列ID来排序:

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

您的状态可能如下所示:

{
  areas: {1: {id: 1, title: 'some title'}, 2: {id: 2, title: 'other title'}},
  areaIds: [1, 2],
}

然后你会像这样迭代:

areaIds.map(id => <Component key={id} area={areas[id]} />)

如果您真的想要Object.entries方式,可以使用像lodash这样的库,它可以让您轻松完成:

_.map(areas, area => <Component key={area.id} area={area} />)