Je suis très nouveau sur React JS (comme dans, vient de commencer aujourd'hui). Je ne comprends pas très bien comment fonctionne setState. Je combine React et Easel JS pour dessiner une grille basée sur l'entrée utilisateur. Voici mon bin JS: http://jsbin.com/zatula/edit?js,output
Voici le 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")
);
Vous pouvez voir dans le chutier JS lorsque vous modifiez le nombre de lignes ou de colonnes avec l'un des menus déroulants, rien ne se passera la première fois. La prochaine fois que vous modifiez une valeur de liste déroulante, la grille se dessine sur les valeurs de ligne et de colonne de l'état précédent. Je suppose que cela se produit parce que ma fonction this.drawGrid () s'exécute avant que setState ne soit terminé. Il y a peut-être une autre raison?
Merci pour votre temps et votre aide!
la source
this.drawGrid()
danscomponentDidUpdate
comme @kennedyyu suggéré, parce que tout le tempssetState
est terminé, je veux redessiner la grille (donc cela permettrait d' économiser quelques lignes de code), mais faire la même chose .render
sera appelé à chaque fois que vous effectuerez unsetState
nouveau rendu du composant en cas de modifications. Si vous déplacez votre appeldrawGrid
là-bas plutôt que de l'appeler dans vosupdate*
méthodes, vous ne devriez pas avoir de problème.Si cela ne fonctionne pas pour vous, il y a également une surcharge
setState
qui prend un rappel comme deuxième paramètre. Vous devriez pouvoir en profiter en dernier recours.la source
render: function() { this.drawGrid(); return......
render()
... la réponse de sytolk devrait être celle acceptéesetState
devrait être utilisé en dernier recours. Je suis d'accord avec la plupart des gens ici pour dire qu'il est logique d'utiliser cette approche.react
le vdom prendrait soin de ne pas faire trop de travail dans la plupart des cas, c'est l'interopérabilité avec une autre bibliothèque que vous souhaitez minimiserFaire
setState
revenir unPromise
En plus de passer une méthode
callback
tosetState()
, vous pouvez l'envelopper autour d'uneasync
fonction et utiliser lathen()
méthode - qui dans certains cas peut produire un code plus propre:Et ici, vous pouvez prendre cette longueur d'avance et créer une
setState
fonction réutilisable qui, à mon avis, est meilleure que la version ci-dessus:Cela fonctionne bien dans React 16.4, mais je ne l'ai pas encore testé dans les versions antérieures de React .
Il convient également de mentionner que conserver votre code de rappel dans
componentDidUpdate
method est une meilleure pratique dans la plupart - probablement tous les cas.la source
lorsque de nouveaux accessoires ou états sont reçus (comme vous appelez
setState
ici), React invoquera certaines fonctions, qui sont appeléescomponentWillUpdate
etcomponentDidUpdate
dans votre cas, ajoutez simplement une
componentDidUpdate
fonction à appelerthis.drawGrid()
voici le code de travail dans JS Bin
comme je l'ai mentionné, dans le code,
componentDidUpdate
sera invoqué aprèsthis.setState(...)
alors à l'
componentDidUpdate
intérieur va appelerthis.drawGrid()
en savoir plus sur le cycle de vie des composants dans React https://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate
la source