返回成对元素反应JSX
问题描述:
问题:返回成对元素反应JSX
在反应,要通过映射的阵列来创建DOM结构,但在阵列中的每个项目应该返回2个元素。例如
import React from 'react'
import _ from 'lodash'
let { Component } = React
export default class DataList extends Component {
render() {
let array = [
{def: 'item1', term: 'term1', obj1: 'rand'},
{def: 'item2', term: 'term2'}
]
return (
<dl>
{_.map(array, (item) => {
return (
<dt>{item.def}</dt>
<dd>{item.term}</dd>
)
})}
</dl>
)
}
}
React不让你渲染兄弟姐妹而不把它们包装在一个容器元素中,这会破坏这里的DOM结构。
答
你可以做一些与reduce
简单的是这样的:
import React, { Component } from 'react';
export default class DataList extends Component {
render() {
const array = [
{def: 'item1', term: 'term1', obj1: 'rand'},
{def: 'item2', term: 'term2'}
];
return (
<dl>
{array.reduce((acc, item, idx) => {
return acc.concat([
<dt key={`def-${idx}`}>{item.def}</dt>,
<dd key={`term-${idx}`}>{item.term}</dd>
]);
}, [])}
</dl>
);
}
}
答
我发现实现这个最简单的方法是映射到对象键(lodash支持这个)为数组的每个项目和有条件地呈现每种类型的元素。
import React from 'react'
import _ from 'lodash'
let { Component } = React
export default class DataList extends Component {
render() {
let array = [
{def: 'item1', term: 'term1', obj1: 'rand'},
{def: 'item2', term: 'term2'}
]
return (
<dl>
{_.map(array, (item) => {
return _.map(item, (elem, key) => {
if (key === 'def') {
return <dt>{elem}</dt>
} else if (key === 'term') {
return <dd>{elem}</dd>
}
})
})}
</dl>
)
}
}
答
阵营16.2增加了对Fragments
支持,您可以使用它像这样:
return (
<dl>
{_.map(array, (item) => {
return (
<Fragment>
<dt>{item.def}</dt>
<dd>{item.term}</dd>
</Fragment>
)
})}
</dl>
)
你也可以使用像这样的空标签的片段:
return (
<dl>
{_.map(array, (item) => {
return (
<>
<dt>{item.def}</dt>
<dd>{item.term}</dd>
</>
)
})}
</dl>
)
但是请记住,如果你想使用key
属性上Fragment
标签,你必须使用完整版本的它。更多关于this react的博客
哈,非常好......我花了几秒钟才弄清楚它是如何工作的,这是唯一的缺点(即从代码可读性POV稍微难以理解),但是很多更优雅的解决方案,以及我将从现在开始使用的解决方案。 – stukennedy
还有一件事:通常不建议您使用阵列中的索引作为关键字。这里有一篇很棒的文章:https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318 – Kiril