如何在 React 中使用 map 输出嵌套对象的内容?
How to output content of a nested object using map in React?
我有一个 json 如下所示
const assessmentData = [
{
"Sit1": [
{
"rule": "Rule1",
"type": "High"
}
]
},
{
"Sit2": [
{
"rule": "Rule6",
"type": "Low"
}
]
},
{
"Sit3": [
{
"rule": "Rule3",
"type": "High"
}
]
}
]
现在我想渲染一些包含上述信息的 html。通常在香草 HTML,这就是我所做的
let content = ""
for(let i=0; i < assessmentData.length; i++) {
for (const [key, value] of Object.entries(assessmentData[i])) {
content += `<h2>${key}<h2>`
for (const [subkey, subvalue] of Object.entries(value)) {
const rule = subvalue["rule"]
content += `<h3>${rule}</h3>`
}
}
}
所以最终输出看起来像
<h2>Sit1<h2><h3>Rule1</h3><h2>Sit2<h2><h3>Rule1</h3><h2>Sit3<h2><h3>Rule1</h3>
但我无法使用 map
功能做同样的事情。所以我在 react
中的代码看起来像
const CreateTemplate = (assessmentData) => {
const content = assessmentData.map((item, idx) => {
Object.keys(item).map((subitem, subindex) => {
<h2>{subitem}</h2>
Object.keys(item[subitem]).map((subitem2, subindex2) => {
<h3>{item[subitem][subitem2]["rule"]}</h3>
})
})
});
return (
<div>Content</div>
{content}
)
}
export default CreateTemplate
不输出content
部分。我做错了什么?
您应该 return 来自地图回调的值。 * 您还可以使用 Object.entries
映射键值对数组。由于该值已经是一个数组,因此您不需要使用键 A.K.A。数组索引,您可以简单地映射数组值。
const content = assessmentData.map((item, idx) => {
return Object.entries(item).map(([key, value], subindex) => {
return (
<React.Fragment key={subindex}>
<h2>{key}</h2>
{value.map((subitem2, subindex2) => {
return <h3 key={subindex2}>{subitem2.rule}</h3>
})}
</React.Fragment>
);
});
});
* 我尝试匹配所有括号,但希望您的 IDE 比我在纯文本编辑器中做得更好
或者使用隐式箭头函数returns:
const content = assessmentData.map((item, idx) =>
Object.entries(item).map(([key, value], subindex) => (
<React.Fragment key={subindex}>
<h2>{key}</h2>
{value.map((subitem2, subindex2) => (
<h3 key={subindex2}>{subitem2.rule}</h3>
))}
</React.Fragment>
))
);
此外,作为一般问题的解决方案,您可以提出递归遍历对象或具有可变深度的数组,也许对某些人有用。
window.Fragment = React.Fragment
const assessmentData = [
{
"Sit1": [
{
"rule": "Rule1",
"type": "High"
}
]
},
{
"Sit2": [
{
"rule": "Rule6",
"type": "Low"
}
]
},
{
"another example:" : [
{items: [1, 2]}, {other: [4, 5, 6]}
]
}
]
const getObject = (obj, level) => {
return Object.entries(obj).map(([key, val], i) => {
return <Fragment key={`key${i}`}>{getTree(key, level + 1)}{getTree(val, level + 2)}</Fragment>
})
}
const getArray = (arr, level) => {
return arr.map((e, i) => {
return <Fragment key={`key${i}`}>{getTree(e, level + 1)}</Fragment>
})
}
const getTree = (data, level=0) => {
if (data instanceof Array) {
return getArray(data, level)
} else if (data instanceof Object) {
return getObject(data, level)
}
return <p style={{fontSize:`${20 - level}px`, paddingLeft: `${level}em`}}>{data}</p>
}
const App = () => {
return (
<div>
{ getTree(assessmentData) }
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
* {
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
我有一个 json 如下所示
const assessmentData = [
{
"Sit1": [
{
"rule": "Rule1",
"type": "High"
}
]
},
{
"Sit2": [
{
"rule": "Rule6",
"type": "Low"
}
]
},
{
"Sit3": [
{
"rule": "Rule3",
"type": "High"
}
]
}
]
现在我想渲染一些包含上述信息的 html。通常在香草 HTML,这就是我所做的
let content = ""
for(let i=0; i < assessmentData.length; i++) {
for (const [key, value] of Object.entries(assessmentData[i])) {
content += `<h2>${key}<h2>`
for (const [subkey, subvalue] of Object.entries(value)) {
const rule = subvalue["rule"]
content += `<h3>${rule}</h3>`
}
}
}
所以最终输出看起来像
<h2>Sit1<h2><h3>Rule1</h3><h2>Sit2<h2><h3>Rule1</h3><h2>Sit3<h2><h3>Rule1</h3>
但我无法使用 map
功能做同样的事情。所以我在 react
中的代码看起来像
const CreateTemplate = (assessmentData) => {
const content = assessmentData.map((item, idx) => {
Object.keys(item).map((subitem, subindex) => {
<h2>{subitem}</h2>
Object.keys(item[subitem]).map((subitem2, subindex2) => {
<h3>{item[subitem][subitem2]["rule"]}</h3>
})
})
});
return (
<div>Content</div>
{content}
)
}
export default CreateTemplate
不输出content
部分。我做错了什么?
您应该 return 来自地图回调的值。 * 您还可以使用 Object.entries
映射键值对数组。由于该值已经是一个数组,因此您不需要使用键 A.K.A。数组索引,您可以简单地映射数组值。
const content = assessmentData.map((item, idx) => {
return Object.entries(item).map(([key, value], subindex) => {
return (
<React.Fragment key={subindex}>
<h2>{key}</h2>
{value.map((subitem2, subindex2) => {
return <h3 key={subindex2}>{subitem2.rule}</h3>
})}
</React.Fragment>
);
});
});
* 我尝试匹配所有括号,但希望您的 IDE 比我在纯文本编辑器中做得更好
或者使用隐式箭头函数returns:
const content = assessmentData.map((item, idx) =>
Object.entries(item).map(([key, value], subindex) => (
<React.Fragment key={subindex}>
<h2>{key}</h2>
{value.map((subitem2, subindex2) => (
<h3 key={subindex2}>{subitem2.rule}</h3>
))}
</React.Fragment>
))
);
此外,作为一般问题的解决方案,您可以提出递归遍历对象或具有可变深度的数组,也许对某些人有用。
window.Fragment = React.Fragment
const assessmentData = [
{
"Sit1": [
{
"rule": "Rule1",
"type": "High"
}
]
},
{
"Sit2": [
{
"rule": "Rule6",
"type": "Low"
}
]
},
{
"another example:" : [
{items: [1, 2]}, {other: [4, 5, 6]}
]
}
]
const getObject = (obj, level) => {
return Object.entries(obj).map(([key, val], i) => {
return <Fragment key={`key${i}`}>{getTree(key, level + 1)}{getTree(val, level + 2)}</Fragment>
})
}
const getArray = (arr, level) => {
return arr.map((e, i) => {
return <Fragment key={`key${i}`}>{getTree(e, level + 1)}</Fragment>
})
}
const getTree = (data, level=0) => {
if (data instanceof Array) {
return getArray(data, level)
} else if (data instanceof Object) {
return getObject(data, level)
}
return <p style={{fontSize:`${20 - level}px`, paddingLeft: `${level}em`}}>{data}</p>
}
const App = () => {
return (
<div>
{ getTree(assessmentData) }
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
* {
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>