He escrito código para mostrar la repetición de elementos en ReactJS, pero no me gusta lo feo que es.

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>
  );
} 

Existe una mejor manera de lograr esto?

(Me gustaría incrustar for bucles en el código de la plantilla, o algún método similar.)

InformationsquelleAutor fadedbee | 2014-09-03

5 Comentarios

  1. 124

    Usted puede poner expresiones dentro de llaves. Aviso en el que se compila a JavaScript por qué un for bucle nunca sería posible dentro de JSX sintaxis; JSX cantidades a las llamadas de función y azúcar que los argumentos de la función. Sólo se permiten las expresiones.

    (También: Recuerde agregar key los atributos de los componentes que representan dentro de bucles.)

    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:

    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);
                  })
                )
              );
            })
          )
        )
      );
    } 
    • Bonitas capturas. He añadido la falta paréntesis en la parte superior y se pasó de for a un map. Ya no sé lo que los datos se encuentran en cada una de las estructuras de datos, supuse que las filas son las matrices y se utiliza el índice de la iteración de la key. Cuando los datos se agrega/quita de la matriz, que hará innecesario volver a renderizar. Usted debe cambiar key a un valor que identifica los datos y que no depende de la orden y/o el tamaño de la matriz.
    • Gracias por tu respuesta. Voy a dejar esta pregunta abierta para un par de días, en el caso de que hay una manera mejor de hacer esto, antes de aceptar su respuesta. Creo que mi problema es que JSX no tienen, al parecer, no la expresión de escape, para for y lazos similares, ni tampoco tiene la plantilla de sintaxis para los bucles.
    • JSX no es un lenguaje de plantillas, es azúcar sintáctico para JavaScript antiguos. Usted no obtendrá los operadores como usted espera de idiomas de la plantilla. Trate de pegar el código en esta respuesta en el live JSX compilador para entender lo que está haciendo y por qué un for bucle nunca sería posible.
    • Puede agregar evento onClick de cada fila y pasar la fila elemento a la función? Estoy tratando de hacer algo como esto, pero estoy recibiendo Uncaught TypeError: No se puede leer la propiedad ‘clickHandler’ undefined clickHandler() { console.log(‘el clic de la fila’); } <tbody> {este.props.las filas.mapa(function(fila i) { return ( <tr clave={i} onClick=este.clickHandler()> {fila.mapa(function(col, j) { return <td clave={j}>{col}</td>; })} </tr> ); })} </tbody>
    • Nunca la mente, yo he añadido .bind(este) a la mapa método el método es involucrarse para cada fila. Gracias.
  2. 12

    Para ampliar Ross Allen respuesta, aquí es un poco más limpio variante utilizando ES6 flecha sintaxis.

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

    Tiene la ventaja de que el JSX parte es aislado (no return o ;), lo que es más fácil poner un círculo alrededor de él.

  3. 11

    Superficial (a través de la Matriz de de():

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

    Otra manera sería a través de la Matriz de fill():

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

    Nodos Anidados:

    JS:

     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'))

    CSS:

    td{ border:1px solid silver; padding:1em; }

    HTML:

    <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>

    • Pasé al menos 2 horas para poder bucle dentro del bucle en el procesamiento de la función. gracias. usted salvó mi día.
    • No podía hacer esto en lugar de usar el mapa? Array.from({length: 5}, (value, index) => <tr />)
    • sí, gracias!, actualizada la respuesta
  4. 2

    En el espíritu de la programación funcional, vamos a hacer nuestros componentes un poco más fácil trabajar con abstracciones.

    //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);

    Ahora podemos definir nuestro render como este:

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

    jsbin


    Una alternativa a nuestro map2d sería un curry función de mapa, pero las personas tienden a alejarse de las alarmada.

    • Esas funciones no dan el dev la oportunidad de especificar la key atributo. Mediante el uso del índice significa que agregar/quitar elementos de la fuerza re-representación de los objetos que quizá no han cambiado.
    • Cierto, pero el 95% del tiempo el índice basado en claves son suficientes. Prefiero ir un poco fuera del camino en el un tanto raras excepciones.
    • De acuerdo, sería muy fácil para asegurarse de que las claves son únicas en cualquier nivel dado, si necesario fuese, me gusta.
  5. 1

    Esto es, la omi, la forma más elegante de hacerlo (con ES6). Crear una instancia vacía la matriz de 7 índices y mapa en una sola línea:

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

    felicitaciones a
    https://php.quicoto.com/create-loop-inside-react-jsx/

    • Bueno! Parece que usted también puede hacer Array(...Array(10)).map((v, i) => <SomeComponent />)

Dejar respuesta

Please enter your comment!
Please enter your name here