Ich bin sehr neu in React JS (wie in, gerade erst heute begonnen). Ich verstehe nicht ganz, wie setState funktioniert. Ich kombiniere React und Easel JS, um ein Raster basierend auf Benutzereingaben zu zeichnen. Hier ist mein JS-Bin: http://jsbin.com/zatula/edit?js,output
Hier ist der Code:
var stage;
var Grid = React.createClass({
getInitialState: function() {
return {
rows: 10,
cols: 10
}
},
componentDidMount: function () {
this.drawGrid();
},
drawGrid: function() {
stage = new createjs.Stage("canvas");
var rectangles = [];
var rectangle;
//Rows
for (var x = 0; x < this.state.rows; x++)
{
// Columns
for (var y = 0; y < this.state.cols; y++)
{
var color = "Green";
rectangle = new createjs.Shape();
rectangle.graphics.beginFill(color);
rectangle.graphics.drawRect(0, 0, 32, 44);
rectangle.x = x * 33;
rectangle.y = y * 45;
stage.addChild(rectangle);
var id = rectangle.x + "_" + rectangle.y;
rectangles[id] = rectangle;
}
}
stage.update();
},
updateNumRows: function(event) {
this.setState({ rows: event.target.value });
this.drawGrid();
},
updateNumCols: function(event) {
this.setState({ cols: event.target.value });
this.drawGrid();
},
render: function() {
return (
<div>
<div className="canvas-wrapper">
<canvas id="canvas" width="400" height="500"></canvas>
<p>Rows: { this.state.rows }</p>
<p>Columns: {this.state.cols }</p>
</div>
<div className="array-form">
<form>
<label>Number of Rows</label>
<select id="numRows" value={this.state.rows} onChange={ this.updateNumRows }>
<option value="1">1</option>
<option value="2">2</option>
<option value ="5">5</option>
<option value="10">10</option>
<option value="12">12</option>
<option value="15">15</option>
<option value="20">20</option>
</select>
<label>Number of Columns</label>
<select id="numCols" value={this.state.cols} onChange={ this.updateNumCols }>
<option value="1">1</option>
<option value="2">2</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="12">12</option>
<option value="15">15</option>
<option value="20">20</option>
</select>
</form>
</div>
</div>
);
}
});
ReactDOM.render(
<Grid />,
document.getElementById("container")
);
Sie können im JS-Bin sehen, dass beim ersten Ändern der Anzahl der Zeilen oder Spalten mit einem der Dropdowns nichts passiert. Wenn Sie das nächste Mal einen Dropdown-Wert ändern, zeichnet das Raster die Zeilen- und Spaltenwerte des vorherigen Status. Ich vermute, dass dies geschieht, weil meine Funktion this.drawGrid () ausgeführt wird, bevor setState abgeschlossen ist. Vielleicht gibt es noch einen anderen Grund?
Vielen Dank für Ihre Zeit und Hilfe!
quelle
this.drawGrid()
incomponentDidUpdate
wie @kennedyyu vorgeschlagen, weil zu jeder ZeitsetState
beendet ist, werde ich das Gitter neu gezeichnet werden soll (so würde dies einige Zeilen Code speichern), aber erreichen die gleiche Sache .render
wird jedes Mal aufgerufen, wenn SiesetState
die Komponente bei Änderungen erneut rendern. Wenn Sie Ihren AufrufdrawGrid
dorthin verschieben, anstatt ihn in Ihrenupdate*
Methoden aufzurufen , sollten Sie kein Problem haben.Wenn das bei Ihnen nicht funktioniert, gibt es auch eine Überlastung
setState
, bei der ein Rückruf als zweiter Parameter verwendet wird. Sie sollten dies als letzten Ausweg nutzen können.quelle
render: function() { this.drawGrid(); return......
render()
... sytolks Antwort sollte die akzeptierte seinsetState
als letztes Mittel verwendet werden sollte. Ich stimme den meisten Leuten hier zu, dass es sinnvoll ist, diesen Ansatz zu verwenden.react
wäre, würde das vdom in den meisten Fällen dafür sorgen, dass nicht zu viel Arbeit geleistet wird. Dies ist eine Interop mit einer anderen Bibliothek, die Sie minimieren möchtenEtwas herstellen
setState
Rückkehr einPromise
Zusätzlich zur Übergabe einer
callback
to-setState()
Methode können Sie sie um eineasync
Funktion wickeln und diethen()
Methode verwenden. In einigen Fällen kann dies zu einem saubereren Code führen:Und hier können Sie noch einen Schritt weiter gehen und eine wiederverwendbare
setState
Funktion erstellen , die meiner Meinung nach besser ist als die obige Version:Dies funktioniert gut in React 16.4, aber ich habe es in früheren Versionen von React noch nicht getestet .
Erwähnenswert ist auch, dass es in den meisten - wahrscheinlich allen Fällen - besser ist , Ihren Rückrufcode in der
componentDidUpdate
Methode zu belassen.quelle
Wenn neue Requisiten oder Zustände empfangen werden (wie Sie
setState
hier anrufen ), ruft React einige Funktionen auf, die aufgerufen werdencomponentWillUpdate
undcomponentDidUpdate
Fügen Sie in Ihrem Fall einfach eine
componentDidUpdate
aufzurufende Funktion hinzuthis.drawGrid()
Hier ist Arbeitscode in JS Bin
Wie bereits erwähnt, wird im Code danach
componentDidUpdate
aufgerufenthis.setState(...)
dann wird
componentDidUpdate
drinnen anrufenthis.drawGrid()
Weitere Informationen zum Komponentenlebenszyklus finden Sie unter Reagieren unter https://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate
quelle