una tiempo termine que otra función funciones funcion esperar ejecutar después despues completar javascript reactjs setstate

javascript - tiempo - ¿Puedo ejecutar una función después de que setState haya terminado de actualizar?



esperar que termine una funcion javascript (4)

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 se complete setState. Tal vez hay otra razón?

¡Gracias por tu tiempo y ayuda!


Hacer que setState devuelva una Promise

Además de pasar una callback de callback al método setState() , puede setState() alrededor de una función async y usar el método then() , que en algunos casos puede producir un código más limpio:

(async () => new Promise(resolve => this.setState({dummy: true}), resolve)() .then(() => { console.log(''state:'', this.state) });

Y aquí puede dar un paso más y hacer una función setState reutilizable que, en mi opinión, es mejor que la versión anterior:

const promiseState = async state => new Promise(resolve => this.setState(state, resolve)); promiseState({...}) .then(() => promiseState({...}) .then(() => { ... // other code return promiseState({...}); }) .then(() => {...});

Esto funciona bien en React 16.4, pero aún 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 método componentDidUpdate es una mejor práctica en la mayoría, probablemente en todos los casos.


cuando se reciben nuevos accesorios o estados (como llama a setState aquí), React invocará algunas funciones, que se llaman componentWillUpdate y componentDidUpdate

en su caso, simplemente agregue una función componentDidUpdate para llamar a this.drawGrid()

aquí está el código de trabajo en JS Bin

Como mencioné, en el código, se invocará componentDidUpdate después de this.setState(...)

entonces componentDidUpdate dentro va a llamar a this.drawGrid()

Lea más sobre el ciclo de vida del componente en React https://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate


render llamará a render cada vez que setState para volver a renderizar el componente si hay cambios. Si mueve su llamada a drawGrid allí en lugar de llamarla en sus métodos de update* , no debería tener ningún problema.

Si eso no funciona para usted, también hay una sobrecarga de setState que toma una devolución de llamada como segundo parámetro. Debería poder aprovechar eso como último recurso.