Ich habe Code geschrieben, um sich wiederholende Elemente in ReactJS zu rendern, aber ich hasse es, wie hässlich es ist.
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>
);
}
Gibt es einen besseren Weg, um dies zu erreichen?
(Ich möchte for
Schleifen in den Vorlagencode oder einen ähnlichen Ansatz einbetten .)
javascript
reactjs
Fadedbee
quelle
quelle
Antworten:
Sie können Ausdrücke in geschweifte Klammern setzen. Beachten Sie im kompilierten JavaScript, warum eine
for
Schleife innerhalb der JSX-Syntax niemals möglich wäre. JSX entspricht Funktionsaufrufen und gezuckerten Funktionsargumenten. Es sind nur Ausdrücke zulässig.(Außerdem: Denken Sie daran
key
, Komponenten, die in Schleifen gerendert werden , Attribute hinzuzufügen .)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); }) ) ); }) ) ) ); }
quelle
for
zu amap
. Da ich nicht weiß, was die Daten in jeder der Datenstrukturen sind, habe ich angenommen, dass die Zeilen Arrays sind, und den Index der Iteration für die verwendetkey
. Wenn Daten zum Array hinzugefügt / daraus entfernt werden, führt dies zu unnötigem erneuten Rendern. Sie solltenkey
zu einem Wert wechseln , der die Daten eindeutig identifiziert und nicht von der Reihenfolge und / oder Größe des Arrays abhängt.for
Schleifen und ähnliches zu haben scheint , noch eine Vorlagensyntax für Schleifen hat.for
Schleife niemals möglich wäre.Um die Antwort von Ross Allen zu erweitern, finden Sie hier eine etwas sauberere Variante mit ES6-Pfeilsyntax.
{this.props.titles.map(title => <th key={title}>{title}</th> )}
Es hat den Vorteil, dass der JSX-Teil isoliert ist (nein
return
oder;
), was es einfacher macht, eine Schleife um ihn herum zu legen.quelle
Da
Array(3)
ein nicht iterierbares Array erstellt wird , muss es ausgefüllt werden, um die Verwendung dermap
Array-Methode zu ermöglichen. Eine Möglichkeit zum "Konvertieren" besteht darin, es in Array-Klammern zu zerstören, wodurch das Array "gezwungen" wird, mitundefined
Werten gefüllt zu werdenArray(N).fill(undefined)
<table> { [...Array(3)].map((_, index) => <tr key={index}/>) } </table>
Ein anderer Weg wäre über Array
fill()
:<table> { Array(3).fill(<tr/>) } </table>
Das Problem mit dem obigen Beispiel ist das Fehlen von
key
Requisiten, was ein Muss ist .(Verwenden eines Iterators
index
wiekey
nicht empfohlen)Verschachtelte Knoten:
const tableSize = [3,4] const Table = ( <table> <tbody> { [...Array(tableSize[0])].map((tr, trIdx) => <tr key={trIdx}> { [...Array(tableSize[1])].map((a, tdIdx, arr) => <td key={trIdx + tdIdx}> {arr.length * trIdx + tdIdx + 1} </td> )} </tr> )} </tbody> </table> ); ReactDOM.render(Table, document.querySelector('main'))
td{ border:1px solid silver; padding:1em; }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <main></main>
quelle
Array.from({length: 5}, (value, index) => <tr />)
Lassen Sie uns im Sinne der funktionalen Programmierung die Arbeit mit unseren Komponenten mithilfe von Abstraktionen etwas vereinfachen.
// 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);
Jetzt können wir unseren Render folgendermaßen definieren:
render: function(){ return ( <table> <thead>{this.props.titles.map(th)}</thead> <tbody>{map2d(tr, td, this.props.rows)}</tbody> </table> ); }
jsbin
Eine Alternative zu unserer map2d wäre eine Curry-Map-Funktion, aber die Leute scheuen das Currying.
quelle
key
Attribut anzugeben . Die Verwendung des Index bedeutet, dass durch Hinzufügen / Entfernen von Elementen das erneute Rendern von Objekten erzwungen wird, die sich möglicherweise nicht geändert haben.Dies ist imo der eleganteste Weg, dies zu tun (mit ES6). Instanziieren Sie Ihr leeres Array mit 7 Indizes und ordnen Sie es in einer Zeile zu:
Array.apply(null, Array(7)).map((i)=> <Somecomponent/> )
Ein großes Lob an https://php.quicoto.com/create-loop-inside-react-jsx/
quelle
Array(...Array(10)).map((v, i) => <SomeComponent />)