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()
encomponentDidUpdate
como @kennedyyu sugirió, porque cada vez quesetState
se 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 .render
se le llamará cada vez quesetState
vuelva a representar el componente si hay cambios. Si mueve su llamadadrawGrid
allí 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
setState
que 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 aceptadasetState
debe utilizarse un último recurso estoy de acuerdo con la mayoría de la gente aquí que tiene sentido utilizar este enfoque..react
el 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
setState
volver aPromise
Además de pasar una
callback
alsetState()
método, se puede envolver alrededor de unaasync
funció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
setState
funció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
componentDidUpdate
mé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
setState
aquí), React invocará algunas funciones, que se llamancomponentWillUpdate
ycomponentDidUpdate
en su caso, simplemente agregue una
componentDidUpdate
función para llamarthis.drawGrid()
aquí está el código de trabajo en JS Bin
como mencioné, en el código,
componentDidUpdate
se invocará despuésthis.setState(...)
entonces
componentDidUpdate
adentro 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