【问题标题】:How to have nested loops with map in JSX?如何在 JSX 中使用 map 嵌套循环?
【发布时间】:2018-05-04 06:47:49
【问题描述】:

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

【问题讨论】:

  • 你使用的是哪个版本的 React?
  • @MattHolland React 16.1.1

标签: javascript reactjs jsx


【解决方案1】:

我挣扎了一会儿才让我的嵌套地图函数工作,结果发现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>
);

【讨论】:

    【解决方案2】:

    我认为问题在于返回类型应该是数组而不是 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>

    【讨论】:

      【解决方案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>

      【讨论】:

      • 是的,使用一个元素来包装东西使它工作。虽然,根据validator.w3.org/nu,我没有完全使用您的解决方案,因为嵌套的&lt;tr&gt; 无效。相反,我用&lt;tbody&gt; 包装了一些东西,并且在一个表中包含多个&lt;tbody&gt; 是有效的HTML(例如:stackoverflow.com/a/3076790/3486743)。还是谢谢你。
      • 这里的关键是使用2个return语句
      猜你喜欢
      • 1970-01-01
      • 2018-11-03
      • 2020-03-25
      • 2021-11-24
      • 2021-03-02
      • 2021-10-17
      • 2020-07-07
      • 1970-01-01
      • 2021-09-06
      相关资源
      最近更新 更多