Javascript 如何渲染重复的 React 元素?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25646502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 21:39:01  来源:igfitidea点击:

How can I render repeating React elements?

javascriptreactjs

提问by fadedbee

I've written some code to render repeating elements in ReactJS, but I hate how ugly it is.

我已经写了一些代码来渲染 ReactJS 中的重复元素,但我讨厌它有多丑。

render: function(){
  var titles = this.props.titles.map(function(title) {
    return <th>{title}</th>;
  });
  var rows = this.props.rows.map(function(row) {
    var cells = [];
    for (var i in row) {
      cells.push(<td>{row[i]}</td>);
    }
    return <tr>{cells}</tr>;
  });
  return (
    <table className="MyClassName">
      <thead>
        <tr>{titles}</tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
} 

Is there a better way to achieve this?

有没有更好的方法来实现这一目标?

(I would like to embed forloops within the template code, or some similar approach.)

(我想for在模板代码或一些类似的方法中嵌入循环。)

回答by Ross Allen

You can put expressions inside braces. Notice in the compiled JavaScript why a forloop would never be possible inside JSX syntax; JSX amounts to function calls and sugared function arguments. Only expressions are allowed.

您可以将表达式放在大括号内。注意在编译的 JavaScript 中为什么forJSX 语法中永远不可能出现循环;JSX 相当于函数调用和加糖的函数参数。只允许表达式。

(Also: Remember to add keyattributes to components rendered inside loops.)

(另外:记住要添加key的属性里面循环渲染组件)。

JSX + ES2015:

JSX + ES2015

render() {
  return (
    <table className="MyClassName">
      <thead>
        <tr>
          {this.props.titles.map(title =>
            <th key={title}>{title}</th>
          )}
        </tr>
      </thead>
      <tbody>
        {this.props.rows.map((row, i) =>
          <tr key={i}>
            {row.map((col, j) =>
              <td key={j}>{col}</td>
            )}
          </tr>
        )}
      </tbody>
    </table>
  );
} 

JavaScript:

JavaScript:

render: function() {
  return (
    React.DOM.table({className: "MyClassName"}, 
      React.DOM.thead(null, 
        React.DOM.tr(null, 
          this.props.titles.map(function(title) {
            return React.DOM.th({key: title}, title);
          })
        )
      ), 
      React.DOM.tbody(null, 
        this.props.rows.map(function(row, i) {
          return (
            React.DOM.tr({key: i}, 
              row.map(function(col, j) {
                return React.DOM.td({key: j}, col);
              })
            )
          );
        })
      )
    )
  );
} 

回答by Jodiug

To expand on Ross Allen's answer, here is a slightly cleaner variant using ES6 arrow syntax.

为了扩展 Ross Allen 的答案,这里有一个使用 ES6 箭头语法的更简洁的变体。

{this.props.titles.map(title =>
  <th key={title}>{title}</th>
)}

It has the advantage that the JSX part is isolated (no returnor ;), making it easier to put a loop around it.

它的优点是 JSX 部分是隔离的(没有return;),更容易在它周围放置一个循环。

回答by vsync

Shallow (via Array from():

浅(通过 Array from()

<table>
    { Array.from({length:3}, (value, index) => <tr key={value.id} />) }
</table>

Another way would be via Array fill():

另一种方法是通过 Array fill()

<table>
    { Array(3).fill(<tr />) }
</table>


Nested Nodes:

嵌套节点:

 var table = (
      <table>
        { Array.from(Array(3)).map((tr, tr_i) => 
            <tr> 
              { Array.from(Array(4)).map((a, td_i, arr) => 
                  <td>{arr.length * tr_i + td_i + 1}</td>
               )}
            </tr>
        )}
      </table>
);

ReactDOM.render(table, document.querySelector('main'))
td{ border:1px solid silver; padding:1em; }
<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>
<main></main>

回答by Brigand

In the spirit of functional programming, let's make our components a bit easier to work with by using abstractions.

本着函数式编程的精神,让我们通过使用抽象使我们的组件更易于使用。

// converts components into mappable functions
var mappable = function(component){
  return function(x, i){
    return component({key: i}, x);
  }
}

// maps on 2-dimensional arrays
var map2d = function(m1, m2, xss){
  return xss.map(function(xs, i, arr){
    return m1(xs.map(m2), i, arr);
  });
}

var td = mappable(React.DOM.td);
var tr = mappable(React.DOM.tr);
var th = mappable(React.DOM.th);

Now we can define our render like this:

现在我们可以像这样定义我们的渲染:

render: function(){
  return (
    <table>
      <thead>{this.props.titles.map(th)}</thead>
      <tbody>{map2d(tr, td, this.props.rows)}</tbody>
    </table>
  );
}

jsbin

jsbin



An alternative to our map2d would be a curried map function, but people tend to shy away from currying.

我们的 map2d 的替代方案是柯里化的 map 函数,但人们往往回避柯里化。

回答by Chris

This is, imo, the most elegant way to do it (with ES6). Instantiate you empty array with 7 indexes and map in one line:

这是,imo,最优雅的方式(使用 ES6)。用 7 个索引实例化你的空数组并在一行中映射:

Array.apply(null, Array(7)).map((i)=>
<Somecomponent/>
)

kudos to https://php.quicoto.com/create-loop-inside-react-jsx/

感谢 https://php.quicoto.com/create-loop-inside-react-jsx/