如何在 JSX 中使用 map 嵌套循环?

IT技术 javascript reactjs jsx
2021-04-16 19:31:43

我无法实现有两个嵌套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 中嵌套调用?

3个回答

您需要将它包装在一个元素中。

像这样的东西(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>

这里的关键是使用2个return语句
2021-06-04 19:31:43
是的,使用元素来包装东西使它起作用。虽然,<tr>根据validator.w3.org/nu 的说法,我并没有完全使用您的解决方案,因为嵌套无效相反,我用 包裹了东西<tbody>,并且<tbody>在一个表格中有几个是有效的 HTML(例如:stackoverflow.com/a/3076790/3486743)。不管怎样,谢谢你。
2021-06-21 19:31:43

我努力让我的嵌套 map 函数工作了一段时间,却发现whatreturn很重要。确保您返回的是第二张地图本身,而不仅仅是最终的预期输出:

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>