Я очень новичок в React JS (как, только начал сегодня). Я не совсем понимаю, как работает setState. Я комбинирую React и Easel JS, чтобы нарисовать сетку на основе пользовательского ввода. Вот моя корзина JS: http://jsbin.com/zatula/edit?js,output
Вот код:
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")
);
Вы можете видеть в JS bin, когда вы изменяете количество строк или столбцов одним из выпадающих меню, ничего не произойдет в первый раз. В следующий раз, когда вы измените значение раскрывающегося списка, сетка отобразит значения строки и столбца предыдущего состояния. Я предполагаю, что это происходит, потому что моя функция this.drawGrid () выполняется до завершения setState. Может быть, есть другая причина?
Спасибо за ваше время и помощь!
источник
this.drawGrid()
вcomponentDidUpdate
как @kennedyyu предложил, потому что какое -то времяsetState
закончится, я хочу , чтобы перерисовать сетку (так что это позволит сэкономить несколько строк кода), но сделать то же самое ,render
будет вызываться каждый раз приsetState
повторном рендеринге компонента, если есть изменения. Если вы переместили свой вызовdrawGrid
туда, а не вызывали его в своихupdate*
методах, у вас не должно возникнуть проблем.Если это не работает для вас, есть также перегрузка,
setState
которая принимает обратный вызов в качестве второго параметра. Вы должны быть в состоянии использовать это в качестве крайней меры.источник
render: function() { this.drawGrid(); return......
render()
... ответ Ситолка должен быть принятsetState
должен использоваться в крайнем случае. Я согласен с большинством здесь присутствующих, что имеет смысл использовать этот подход.react
vdom в большинстве случаев позаботился бы о том, чтобы не делать слишком много работы, это взаимодействие с другой библиотекой, которую вы хотите минимизироватьДелая
setState
возвратPromise
В дополнение к передаче метода
callback
tosetState()
вы можете обернуть его вокругasync
функции и использоватьthen()
метод, который в некоторых случаях может привести к созданию более чистого кода:И здесь вы можете сделать еще один шаг вперед и создать функцию многократного использования,
setState
которая, на мой взгляд, лучше, чем в приведенной выше версии:Это хорошо работает в React 16.4, но я еще не тестировал его в более ранних версиях React .
Также стоит упомянуть, что хранение кода обратного вызова в
componentDidUpdate
методе - это лучшая практика в большинстве - возможно, во всех случаях.источник
когда поступают новые реквизиты или состояния (как вы называете
setState
здесь), React будет вызывать некоторые функции, которые вызываютсяcomponentWillUpdate
иcomponentDidUpdate
в вашем случае просто добавьте
componentDidUpdate
функцию для вызоваthis.drawGrid()
вот рабочий код в JS Bin
как я уже упоминал, в коде
componentDidUpdate
будет вызываться послеthis.setState(...)
тогда
componentDidUpdate
внутри будет звонитьthis.drawGrid()
Узнайте больше о жизненном цикле компонента в React https://facebook.github.io/react/docs/component-specs.html#updating-componentwillupdate
источник