[英]How to have nested loops with map in JSX?
我無法實現擁有兩個嵌套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
。
如何在 JSX 中嵌套map
調用?
你需要將它包裝在一個元素中。
像這樣的東西(由於表元素的規則,我添加了一個額外的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>
我認為問題是返回類型應該是一個數組而不是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>
我掙扎了一段時間才能得到我的嵌套的地圖功能只有合作,發現what
,你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>
);
我不確定它在技術上是否正確,但作為助記符,您可以記住:“每個返回的 JSX 元素必須只有一個 JSX 元素”。
因此,大多數情況下,只需將您擁有的內容包裝在<></>
對(或任何其他任意標簽對)中即可解決問題。 例如,如果您從組件的 render 方法返回兩個<div>
,那將是不正確的,但是,如果您將這兩個包裝在<></>
對中,很可能它會被修復。
但請注意,有時它會變得更加模糊,例如,當將兩個 ES6 映射相互嵌套時,例如:
<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>
PS :(來自文檔):您還可以從 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>,
];
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.