如何在 React/JSX 中实现以下网格输出?

How can I achieve the following grid output in React/JSX?

在 Django/Bootstrap 中,有时我想要一个类似于 Pinterest 的对象网格,我在模板中使用以下内容:

<div class="row">
    {% for object in objects %}
        <div className="col-md-3"><!-- Each object code here --></div>
        {% if forloop.counter|divisibleby:"4" and not forloop.last %}
        </div><div class="row">
        {% endif %}
    {% endfor %}
</div>

但是,当我在我的 JSX 模板中尝试行 </div><div className="row"> 时,我收到 Unexpected Token 错误,因为结束 </div> 标记出现在开始 <div> 标记之前(这是分隔对象行的方式,在这种情况下,每行有 4 个对象)。

有没有办法在通过 JSX 语法检查的同时实现这种类型的 row/column 网格?

请记住,JSX 不是模板语言——它直接转换为 JavaScript 函数调用。因此,当您编写 JSX 时,与在 Django/Handlebars/etc 中编写模板不同,您可以随意使用 JavaScript 的全部功能。出于这个原因,通常最好考虑调整数据,以便您可以轻松地对其进行迭代并创建所需的 DOM 结构。 mapreduce 等方法是您的朋友。

例如,假设您想在这样的布局中呈现这八个 "items":

var items = ["one", "two", "three", "four", "five", "six", "seven", "eight"];

您真正想要做的是每四个对象渲染一行,然后为该行中的每个对象渲染一个 div。因此,让我们创建一个以这种方式拆分数据的组件。

var PinterestLayout = React.createClass({
  render: function() {
    // Here we'll just use Lo-dash's `chunk` method to split our data
    // into the right sized groups.
    var groups = _.chunk(this.props.items, 4);
    // Now `groups` is an array of arrays that looks like:
    // [ ["one", "two", "three", "four"],
    //   ["five", "six", "seven", "eight"] ]
    //
    // Let's render a row for each group.
    return <div>{groups.map(this.renderRow)}</div>;
  },

  renderRow: function(row) {
    // Now `row` is just an array of four items,
    // which we can render just how you'd expect.
    return <div className="row">{row.map(this.renderItem)}</div>;
  },

  renderItem: function(item) {
    return <div className="col-sm-3">{item}</div>;
  }
});

这是 JSBin 上的一个工作示例:https://jsbin.com/hawoya/edit?js,output