我无法实现两个嵌套map
:
render() {
return (
<table className="table">
<tbody>
{Object.keys(this.state.templates).map(function(template_name) {
return (
<tr key={template_name}><td><b>Template: {template_name}</b></td></tr>
{this.state.templates[template_name].items.map(function(item) {
return (
<tr key={item.id}><td>{item.id}</td></tr>
)
})}
)
})}
</tbody>
</table>
)
}
这给出了SyntaxError: unknown: Unexpected token
。
如何嵌套map
在JSX中调用?
您需要将其包装在元素中。
类似的东西(由于表元素的规则,我添加了额外的tr
):
render() {
return (
<table className="table">
<tbody>
{Object.keys(templates).map(function (template_name) {
return (
<tr key={template_name}>
<tr>
<td>
<b>Template: {template_name}</b>
</td>
</tr>
{templates[template_name].items.map(function (item) {
return (
<tr key={item.id}>
<td>{item}</td>
</tr>
);
})}
</tr>
);
})}
</tbody>
</table>
);
}
}
运行示例(没有表):
const templates = {
template1: {
items: [1, 2]
},
template2: {
items: [2, 3, 4]
},
};
const App = () => (
<div>
{
Object.keys(templates).map(template_name => {
return (
<div>
<div>{template_name}</div>
{
templates[template_name].items.map(item => {
return(<div>{item}</div>)
})
}
</div>
)
})
}
</div>
);
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我不确定它在技术上是否正确,但是作为 mnemonic 您可以记住:&quot; 每个返回的JSX元素都必须仅为一个JSX元素&quort。
因此,大多数情况下,大多数时候只包装您在<></>
对中的内容(或任何其他任意标签对)都会解决问题。,例如,如果您从渲染中返回了两个<div>
组件的方法,这将是不正确的,但是,如果将这两个包装在<></>
对中,则很可能是 。
<tbody>
{
this.categorizedData.map(
(catgGroup) => (
<tr>
<td>{catgGroup}</td>
</tr>
this.categorizedData[catgGroup].map(
(item) => (
<tr>
<td>{item.name}</td>
<td>{item.price}</td>
</tr>
)
)
)
)
}
</tbody>
可以这样修复:
<tbody>
{
this.categorizedData.map(
(catgGroup) => (
<> // <--- Notice this, it will wrap all JSX elements below in one single JSX element.
<tr>
<td>{catgGroup}</td>
</tr>
{this.categorizedData[catgGroup].map( // <--- Also notice here, we have wrapped it in curly braces, because it is an "expression" inside JSX.
(item) => (
<tr>
<td>{item.name}</td>
<td>{item.price}</td>
</tr>
)
)}
</>
)
)
}
</tbody>
P.S。 :(从文档中):您还可以从React组件中返回一系列元素:
render() {
// No need to wrap list items in an extra element!
return [
// Don't forget the keys :slight_smile:
<li key="A">First item</li>,
<li key="B">Second item</li>,
<li key="C">Third item</li>,
];
}
我挣扎了一段时间,以使我的嵌套地图功能起作用,只是发现 what
you return
至关重要。确保您返回第二张地图本身,而不仅仅是最终预期输出:
let { categories } = data;
categories = categories.map(category =>
category.subcategories.map((subcategory, i) => <h2 key={i}>{subcategory.name}</h2>)
);
return (
<div className="category-container">
<div>{categories}</div>
</div>
);
我认为问题是返回类型应该是数组,而不是react16中的对象。您可以在下面尝试这样的尝试:
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
templates: {
foo: {
items: [
{id: 0},{id:1}
]
},
bar: {
items: [
{id: 2},{id:3}
]
}
}
}
}
renderTemplate = (template, name) => {
let data = []
data = template.items
data.unshift({ name: name })
return data.map((item, index) => <tr key={index}><td>{item.name ? item.name : item.id}</td></tr>)
}
render() {
return (
<table>
<tbody>
{Object.keys(this.state.templates).map(name => {
return this.renderTemplate(this.state.templates[name], name)
})}
</tbody>
</table>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
td {
color: white;
padding: 0 20px;
background: grey;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.1.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.1.1/umd/react-dom.production.min.js"></script>