我正在尝试从嵌套对象数组创建嵌套JSX列表项。 下面是数组:
[
{
"id": 1,
"name": "USA",
"values": [
{
"id": 2,
"name": "Chevy",
"values": [
{
"id": 3,
"name": "Suburban"
},
{
"id": 4,
"name": "Camaro",
"values": [...]
}
]
},
{
"id": 5,
"name": "Ford",
"values": [...]
}
]
}
]
下面是数组应转换为的内容:
<ul>
<li>USA
<ul>
<li>Chevy
<ul>
<li>Suburban</li>
<li>Camaro</li>
</ul>
</li>
<li>Ford</li>
</ul>
</li>
</ul>
这是我的方法:
const resultArray = [];
data.forEach((item) => {
resultArray.push(
<li>{item.name}
)
if(item.values){
//recursively iterate and push into array
}
resultArray.push(</li>); //React does not allow this
});
return resultArray;
React不允许将单独的标记添加到数组中。请帮助提供解决方案。
附注:如果您发现格式化有误,我先向您致歉。这是我第一次在stackOverflow上发帖。
答案 0 :(得分:2)
您可以将孩子“渲染”为变量,然后直接在组件中使用它。 然后,诀窍是使用递归组件。这样,您的树有多深都没关系。如果树变得更深,则无需编辑此组件。
这可能是这样的:
function ListItem({ item }) {
let children = null;
if (item.values) {
children = (
<ul>
{item.values.map(i => <ListItem item={i} key={i.id} />)}
</ul>
);
}
return (
<li>
{item.name}
{children}
</li>
);
}
这是Codesandbox上您的数据的有效示例。
答案 1 :(得分:0)
您应立即将整个节点推入阵列。有一个这样的渲染方法。
const getNode = (data) => {
return (
<ul>
{data.map((item) => (
<li>
USA
<ul>
{item.values && item.values.length
? item.values.map((subItem) => (
<li>
{subItem.name}
<ul>
{subItem.values && subItem.values.length
? subItem.values.map((subSubItem) => <li>{subSubItem.name}</li>)
: null}
</ul>
</li>
))
: null}
</ul>
</li>
))}
</ul>
);
};
然后在渲染函数中使用数据调用该方法
const RenderList = (data) => {
return (
<div>
{ getNode(data) }
</div>
);
};
export default Layout;
答案 2 :(得分:0)
这是一个使用模板的完整解决方案示例,该模板在语法上类似于React。您可以使用Array.prototype.reduce
来简化它。
import { Component, State } from '@stencil/core';
@Component({
tag: 'app-nested-list-demo'
})
export class NestedList {
@State() foo = [
{
name: 'US',
makers: [
{
name: 'Ford',
models: [
{
name: 'Suburban',
mpg: '9000'
},
{
name: 'Escape',
mpg: '300'
}
]
},
{
name: 'GMC',
models: [
{
name: 'Acadia',
mpg: '11'
},
{
name: 'Envoy',
mpg: 'Yukon'
}
]
}
]
},
{
name: 'Japan',
makers: [
{
name: 'Honda',
models: [
{
name: 'CRV',
mpg: '100'
},
{
name: 'Accord',
mpg: '9000'
}
]
},
{
name: 'Toyota',
models: [
{
name: 'Rav4',
mpg: '10'
},
{
name: 'Camry',
mpg: '400'
}
]
}
]
}
];
render() {
const outerList = this.foo.map(country => {
const middleList = country.makers.map(make => {
const innerList = make.models.map(model => {
return (
<li>{model.name} has {model.mpg} MPG</li>
);
});
return (
<li>
{make.name}
<ul>
{innerList}
</ul>
</li>
);
});
return (
<li>
{country.name}
<ul>
{middleList}
</ul>
</li>
);
});
return (
<ul>
{outerList}
</ul>
);
}
}
答案 3 :(得分:0)
我也有同样的问题,但是我已经有了一个脚本,因此我只是在寻找一个更简单的解决方案。此处的脚本可能会有所帮助。