使用React.js在JSX中使用for循环创建HTML

alw*_*arn 7 reactjs react-jsx

我想在JSX中为for循环创建HTML.这是我的尝试看起来像

    function renderTemplates(templates){
           var html = [];
           var templateDiv = [];
           var count  = 0;
           for(var identifier in templates){  
             if(templates.hasOwnProperty(identifier)){
               var templateDetails = templates[identifier];
               if(count == 0){
                  html.push(<Row>);
               }
               cols = <Col md={6}>ff
                          </Col>;
               html.push(cols);
               if(count == 0){
                      html.push(</Row>);
               }
               count = (count === 1)?0:1;
             }
        } 
        return html;
     }
Run Code Online (Sandbox Code Playgroud)

我知道这是错误的语法,但无法弄清楚如何做到这一点.基本上我有一些数据,并希望创建时尚的html,2 divs在1行中.

小智 2

当我查看你的代码时,有两件事引起了我的注意。

第一个是您从 renderTemplates 函数返回一个 React 组件数组。这可能没问题,具体取决于您如何使用输出。要记住的关键是,组件渲染函数的返回值必须是单个 React 组件(例如,如果将此结果包装在另一个 JSX 标记中,那就没问题。)

其次,您似乎没有让数据从顶层组件向下流动;具体来说,您不使用 Row 组件将数据传递给 Column 组件。这就是编写循环如此困难的原因。您无需尝试同时管理行和列,只需将单行所需的数据传递给行组件即可。然后 Row 组件会将每条数据传递给 Column 组件。这消除了处理开始和结束标记的需要,并简化了整体代码。

以下是我所描述内容的示例实现。我使用与表格相关的标签进行渲染,但您可以使用 div 或任何最适合您的标签。在撰写本文时,关于模板中的内容的信息并不多,因此我创建了一个愚蠢的小示例来使用。

var KvpColumn = React.createClass({
    render: function() {
        return <td>{this.props.kvp.key}: {this.props.kvp.value}</td>;
    }
});

var KvpRow = React.createClass({
    render: function() {
        return (
            <tr>
            {this.props.items.map(function(item) {
                return <KvpColumn key={item.key} kvp={item}/>;
            })}
            </tr>
        );
    }
});

var ObjectIDsTable = React.createClass({
    render: function() {
        var templates = this.props.templates;

        var propertyNames = Object.getOwnPropertyNames(templates);
        var group = [];
        var rows = [];
        var cols = Number(this.props.cols) || 2;

        for(var i = 0; i < propertyNames.length; i++) {
            var key = propertyNames[i];

            group.push({key: key, value: templates[key]});
            if(group.length === cols) {
                rows.push(<KvpRow key={group[0].key} items={group}/>);
                group = [];
            }
        }

        if(group.length > 0) { // catch any leftovers
            rows.push(<KvpRow key={group[0].key} items={group}/>);
        }

        return <table>{rows}</table>;
    }
});    

// something silly as a simple example
var templates = { a: 'b', c: 'd', e: 'f', g: 'h', i: 'j' };    
React.render(<ObjectIDsTable templates={templates} cols="2"/>, document.getElementById('app'));
Run Code Online (Sandbox Code Playgroud)

如果您有权使用 Underscore 或 lodash,则可以进一步简化 ObjectIDsTable 中的逻辑(并完全避免编写循环!):

var ObjectIDsTable = React.createClass({
    render: function() {
        var templates = this.props.templates;

        var rows = _.chain(Object.getOwnPropertyNames(templates))
            .map(function(key) { return { key: key, value: templates[key] }; })
            .chunk(this.props.cols || 2)
            .map(function(group) { return <KvpRow key={group[0].key} items={group}/>; })
            .value();

        return <table>{rows}</table>;
    }
});
Run Code Online (Sandbox Code Playgroud)

您可以在Plunker上看到这一点。