如何使用映射函数遍历 reactjs 中的对象列表?



我正在尝试迭代 reactjs 中的对象数组,但面临问题。数组基本上由对象组成,其中每个对象都是表中的一行。

例-

A table like this
| A | B | C |
| 1 | 2 | 3 |
| 4 | 5 | 6 |
would be represented using the following array
[
{"A": 1, "B": 2, "C": 3},
{"A": 4, "B": 5, "C": 6}
]

我正在尝试使用以下语法遍历值 -

this.state.data.map(item =>
Object.entries(item).map(([key, value]) =>
<Column field={key} header={key}>{value}</Column>
))

但这给了我多次串联的所需表。我知道循环存在一些问题,但没有确切地了解困难所在。

python 中的类似情况看起来像 -

for item in array:
for key, value in item.items():
# create a row

假设一个Row组件,你会为外部map的每个回调返回一个Row,像这样(我把它们放在一个假设的Container中只是为了上下文):

<Container>
{this.state.data.amp((item, index) =>
<Row key={index}>
{Object.entries(item).map(([key, value]) =>
<Column field={key} header={key} key={key}>{value}</Column>
)}
</Row>
)}
</Container>

注意 我添加了key属性,因为这些是数组。(对Rowkey使用索引不太理想。如果item对象具有一些唯一属性,则可以改用,那就更好了。如果数组在组件生命周期内从未更改,则使用索引是可以的,但如果更改,则可能导致错误的渲染。更多关于这一点的信息在 React 文档中。

但是,在item上使用Object.entries并不理想,因为它依赖于item中属性的顺序,尽管 JavaScript 对象确实为其属性提供了顺序,但依赖该顺序通常不是最佳实践,因为顺序并不像看起来那么简单,并且构建看似相同的对象但属性顺序不同的东西真的很容易。 相反, 我建议按照您希望它们在列中出现的顺序创建一个属性名称数组,然后使用该数组:

<Container>
{this.state.data.amp((item, index) =>
<Row key={index}>
{propertyNamesInColumnOrder.map(key =>
<Column field={key} header={key} key={key}>{item[key]}</Column>
)}
</Row>
)}
</Container>

¹"构建看似相同的对象但属性顺序不同的东西真的很容易">例如:

const obj1 = {a: 1, b: 2};
const obj2 = {b: 2, a: 1};

这些看起来像同一个对象。它们都具有ab属性,并且属性值相同。但是属性的顺序不同:obj1的属性是按a, b顺序排列的,但obj2的属性是按b, a顺序排列的。

但是等等,情况变得更糟:

const obj3 = {"1": "one", "0": "zero"};
const obj4 = {"0": "zero", "1": "one"};

当然,如果obj1obj2的属性顺序不同,那么obj3obj4的属性顺序就不一样了,对吧?

错。

它们的顺序相同,因为名称是规范中称为"数组索引"的属性(数值为 +0 或正整数的规范数字字符串 ≤ 232- 1)始终按数字顺序排列。

然后你把继承的属性扔进去,情况会变得更糟。因此,一般来说,避免依赖对象属性顺序。

您应该考虑重新调整渲染方式。

我想首先要获取表的thead标题,这可以通过以下方式完成

<thead>
{Object.keys(this.state.data[0]).map((v) => 
<th>{v}</th>)
}
</thead>

然后是可以完成的tbody

<tbody>
{this.state.data.map((v) => 
<tr>
{Object.values(v).map((value) => <td>{value}</td>}
</tr>)
}
</tbody>

参考: https://reactjs.org/docs/thinking-in-react.html

编辑:你可以用GridTableHeadTableBodyRow替换我的theadtbodytrtd的例子,Column你的任何库组件,但你明白了。

最新更新