Soy muy nuevo en React JS (como en, recién comencé hoy). No entiendo cómo funciona setState. Estoy combinando React y Easel JS para dibujar una cuadrícula basada en la entrada del usuario. Aquí está mi bin JS: http://jsbin.com/zatula/edit?js,output
Aquí está el código:
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")
);
Puede ver en el contenedor JS cuando cambia el número de filas o columnas con uno de los menús desplegables, no pasará nada la primera vez. La próxima vez que cambie un valor desplegable, la cuadrícula dibujará los valores de fila y columna del estado anterior. Supongo que esto está sucediendo porque mi función this.drawGrid () se está ejecutando antes de que setState se complete. Tal vez hay otra razón?
¡Gracias por tu tiempo y ayuda!
fuente

this.drawGrid()encomponentDidUpdatecomo @kennedyyu sugirió, porque cada vez quesetStatese termina, me va a querer volver a dibujar la red (por lo que esto ahorraría algunas líneas de código), pero lograr la misma cosa .renderse le llamará cada vez quesetStatevuelva a representar el componente si hay cambios. Si mueve su llamadadrawGridallí en lugar de llamarla en susupdate*métodos, no debería tener ningún problema.Si eso no funciona para usted, también hay una sobrecarga
setStateque toma una devolución de llamada como segundo parámetro. Debería poder aprovechar eso como último recurso.fuente
render: function() { this.drawGrid(); return......render()... la respuesta de sytolk debería ser la aceptadasetStatedebe utilizarse un último recurso estoy de acuerdo con la mayoría de la gente aquí que tiene sentido utilizar este enfoque..reactel Vdom se encargaría de no hacer demasiado trabajo en la mayoría de los casos, esto es interoperabilidad con otra biblioteca que desea minimizarHaciendo
setStatevolver aPromiseAdemás de pasar una
callbackalsetState()método, se puede envolver alrededor de unaasyncfunción y utilizar elthen()método - que en algunos casos puede producir un código más limpio:Y aquí puede dar un paso más y hacer una
setStatefunción reutilizable que, en mi opinión, es mejor que la versión anterior:Esto funciona bien en React 16.4, pero no lo he probado en versiones anteriores de React .
También vale la pena mencionar que mantener el código de devolución de llamada en el
componentDidUpdatemétodo es una mejor práctica en la mayoría, probablemente en todos los casos.fuente
cuando se reciben nuevos accesorios o estados (como se llama
setStateaquí), React invocará algunas funciones, que se llamancomponentWillUpdateycomponentDidUpdateen su caso, simplemente agregue una
componentDidUpdatefunción para llamarthis.drawGrid()aquí está el código de trabajo en JS Bin
como mencioné, en el código,
componentDidUpdatese invocará despuésthis.setState(...)entonces
componentDidUpdateadentro va a llamarthis.drawGrid()Lea más sobre el ciclo de vida del componente en React https://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate
fuente