Eu sou muito novo no React JS (como em, apenas comecei hoje). Não entendo muito bem como o setState funciona. Estou combinando React e Easel JS para desenhar uma grade com base na entrada do usuário. Aqui está o meu bin JS: http://jsbin.com/zatula/edit?js,output
Aqui está o 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")
);
Você pode ver na lixeira JS quando alterar o número de linhas ou colunas com uma das listas suspensas; nada acontecerá na primeira vez. Na próxima vez que você alterar um valor suspenso, a grade será atraída para os valores de linha e coluna do estado anterior. Suponho que isso esteja acontecendo porque minha função this.drawGrid () está sendo executada antes da conclusão de setState. Talvez haja outro motivo?
Obrigado pelo seu tempo e ajuda!
fonte
this.drawGrid()
emcomponentDidUpdate
como @kennedyyu sugerido, porque qualquer momentosetState
está terminado, vou querer redesenhar a grade (de modo que este iria salvar algumas linhas de código), mas realizar a mesma coisa .render
será chamado toda vez que vocêsetState
renderizar novamente o componente, se houver alterações. Se você mudar sua chamada paradrawGrid
lá, em vez de chamá-la em seusupdate*
métodos, não deverá ter problemas.Se isso não funcionar para você, também há uma sobrecarga
setState
que leva um retorno de chamada como um segundo parâmetro. Você deve tirar proveito disso como último recurso.fonte
render: function() { this.drawGrid(); return......
render()
... A resposta de sytolk deve ser o único aceitesetState
deve ser usado um último recurso Concordo com a maioria das pessoas aqui que não faz sentido usar essa abordagem..react
o vdom iria cuidar de não fazer muito trabalho na maioria dos casos, este é de interoperabilidade com outra biblioteca que pretende minimizarFazendo do
setState
retorno umPromise
Além de passar um método
callback
parasetState()
, você pode envolvê-lo em umaasync
função e usar othen()
método - que em alguns casos pode produzir um código mais limpo:E aqui você pode dar mais um passo à frente e criar uma
setState
função reutilizável que, na minha opinião, é melhor que a versão acima:Isso funciona bem no React 16.4, mas não o testei nas versões anteriores do React .
Também vale a pena mencionar que manter o código de retorno de chamada no
componentDidUpdate
método é uma prática recomendada na maioria - provavelmente em todos os casos.fonte
Quando novos adereços ou estados são recebidos (como você chama
setState
aqui), o React invoca algumas funções, chamadascomponentWillUpdate
ecomponentDidUpdate
no seu caso, basta adicionar uma
componentDidUpdate
função para chamarthis.drawGrid()
aqui está trabalhando código no JS Bin
como eu mencionei, no código,
componentDidUpdate
será invocado apósthis.setState(...)
então por
componentDidUpdate
dentro vai chamarthis.drawGrid()
leia mais sobre o Ciclo de vida do componente no React https://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate
fonte