Я уже учился в React.js, написав приложение небольшого калькулятора. Я думал, что все идет хорошо, пока я не узнал, что setState асинхронен, и поэтому мои мутации не сразу применяются.React.js Понимание setState
Таким образом, мой вопрос заключается в том, как наилучшим образом поддерживать текущую сумму на основе значений, добавляемых к вводу. Возьмем следующий пример:
var Calculator = React.createClass({
total : 0,
getInitialState : function(){
return {
value : '0'
};
},
onValueClicked : function (value) {
var actual, total, current = this.state.value;
if(value === '+') {
actual = this.total = parseInt(this.total, 10) + parseInt(current, 10);
} else {
if(parseInt(current, 10) === 0) {
actual = value;
} else {
actual = current.toString() + value;
}
}
this.setState({ value : actual });
},
render : function() {
return (
<div className="calc-main">
<CalcDisplay value={this.state.value} />
<CalcButtonGroup range="0-10" onClick={this.onValueClicked} />
<CalcOpButton type="+" onClick={this.onValueClicked} />
</div>
)
}
});
var CalcDisplay = React.createClass({
render : function() {
return (
<input type="text" name="display" value={this.props.value} />
);
}
});
var CalcButtonGroup = React.createClass({
render : function() {
var i, buttons = [], range = this.props.range.split('-');
for(i = range[0]; i < range[1]; i++) {
var handler = this.props.onClick.bind(null, i);
buttons.push(<CalcNumberButton key={i} onClick={ handler } />);
}
return (
<div className="calc-btn-group">{ buttons }</div>
);
}
});
var CalcNumberButton = React.createClass({
render : function() {
return (
<button onClick={this.props.onClick}>{this.props.key}</button>
);
}
});
var CalcOpButton = React.createClass({
render : function() {
var handler, op = this.props.type;
handler = this.props.onClick.bind(null, op);
return (
<button onClick={handler}>{op}</button>
);
}
});
React.renderComponent(<Calculator />, document.getElementById('container'));
В приведенном выше примере я полностью отказался от хранения суммы в пределах штата и оставил ее снаружи. Я прочитал, что вы можете запустить обратный вызов, когда setState закончил, но в случае калькулятора мне нужно, чтобы он был быстрым и быстро обновлялся. Если состояние не обновляется при каждом нажатии кнопки, и я быстро нажимаю кнопки - все будет выпадать из синхронизации. Является ли обратный вызов всем, что мне не хватает, или я думаю об этом совершенно неправильно?
Любая помощь оценена!
Чтобы быть честным, если вам вообще не нужно использовать 'this.total' в функции' render', то вполне нормально держать его вне состояния. Материал должен находиться в состоянии, только если какое-либо изменение в нем должно «всегда» вызывать повторную визуализацию. Если вам действительно не нужно всегда перерисовывать при изменении this.total, то вы можете оставить вещи такими, какие они есть. –
Если я не ошибаюсь, в текущей реализации, если вы вызываете 'setState' в ответ на событие, состояние будет зависеть до отправки любых дальнейших событий. –
Я думаю, что часть проблемы заключается в том, что я был console.log'ing значения состояния. Однако я обнаружил, что если бы я попытался сохранить более одного элемента в состоянии и изменил одно поле в одном месте, а другое в другом месте - эти два значения выпадут из синхронизации. т. е. если я сохранил операнд в состоянии и проверил его существование в следующем взаимодействии - он не всегда будет установлен. – backdesk