React 不会立即改变状态
React doesn't chang state immediately
美好的一天。我有以下问题:我有一个 class 计算器,它会在单击按钮时更改 firstOperand 参数的状态。但是状态不会立即改变,只有当我再点击一个按钮时它才会改变 firstOperand 的状态。结果是延迟了 1 个操作:我点击了 1 - 指标没有改变,我点击了 2 - 指标变成了 1,我点击了 5 - 指标变成了 12,等等。
这是我的部分代码:
var Indicator = React.createClass({
render: function () {
return (
<div className="calc-indicator">
<input id="indicator" type="text" maxLength="20" size="20" value={this.props.value}/>
</div>
);
}
});
var Button = React.createClass({
render: function () {
return (
<div className="nav-button">
<button type="button" id={this.props.identifier} onClick={this.props.clickHandler}>
{this.props.digit}
</button>
</div>
);
}
});
var Calculator = React.createClass({
setFirstOperand: function (value) {
this.setState(
{
firstOperand: value
}
);
if (isDebug) {
console.log("First operand state is set to " + value + ".");
}
},
setSecondOperand: function (value) {
this.setState(
{
secondOperand: value
}
);
},
changeIndicator: function (value) {
if (isDebug) {
console.log("///Change indicator method is working///");
console.log("change indicator parameter is " + value);
console.log("first operand is " + this.state.firstOperand);
console.log("second operand is " + this.state.secondOperand);
console.log("operation is " + this.state.operation);
}
if (!value) { // if value hasn't been gotten
value = '';
if (this.state.firstOperand) {
value += this.state.firstOperand;
} else {
value = '0';
}
if (this.state.operation) {
value += this.state.operation;
}
if (this.state.secondOperand) {
value += this.state.secondOperand;
}
}
this.setState(
{
value: value
}
);
if (isDebug) {
console.log("indicator is changed to " + value);
console.log("/////////////////////////////////////");
}
},
getInitialState: function () {
calculator = this;
return {
firstOperand: null,
secondOperand: null,
operation: null,
divisionByZero: false,
value: '0'
};
},
cipherClicked: function (event) {
if (this.state.divisionByZero) {
this.setDivisionByZero(false);
}
var newValue = event.target.innerHTML;
var firstValue = this.state.firstOperand;
var secondValue = this.state.secondOperand;
var operation = this.state.operation;
if (operation) {
if (secondValue) {
secondValue = secondValue + newValue;
} else {
secondValue = newValue;
}
if (isDebug) {
console.log("Second operand state is setting to " + secondValue + ".");
}
this.setSecondOperand(secondValue);
} else {
if (firstValue) {
firstValue = firstValue + newValue;
} else {
if (newValue != 0) { // if indicator contains 0 and you have tried to add one 0 more
firstValue = newValue;
}
}
if (isDebug) {
console.log("First operand state is setting to " + firstValue + ".");
}
this.setFirstOperand(firstValue);
setOperand(firstValue);
}
if (isDebug) {
console.log("Calling changeIndicator function.");
}
this.changeIndicator();
},
render: function () {
return (
<div id="calculator">
<table>
<tr>
<td colSpan="4">
<Indicator value={this.state.value} />
</td>
</tr>
<tr>
<td>
<Button identifier="MC" digit="MC" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="MR" digit="MR" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="M+" digit="M+" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="M" digit="M" clickHandler={this.memoryNavigationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="BS" digit="BS" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="CL" digit="CL" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="C" digit="C" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="negate" digit="+-" clickHandler={this.negateClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="7" digit="7" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="8" digit="8" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="9" digit="9" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="divide" digit="/" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="4" digit="4" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="5" digit="5" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="6" digit="6" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="multiply" digit="*" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="1" digit="1" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="2" digit="2" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="3" digit="3" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="minus" digit="-" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="0" digit="0" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="dot" digit="." clickHandler={this.dotClicked}/>
</td>
<td>
<Button identifier="eq" digit="=" clickHandler={this.operationClicked}/>
</td>
<td>
<Button identifier="plus" digit="+" clickHandler={this.operationClicked}/>
</td>
</tr>
</table>
</div>
);
}
});
React.render(<Calculator />, document.body);
</script>
</body>
</html>
根据我的 React Native 回答 ,setState
可以是异步操作,而不是同步操作。这意味着状态更新可以一起批处理,而不是立即完成,以获得性能提升。如果你真的需要在状态真正更新后做一些事情,有一个回调参数:
this.setState({ searchString: event.nativeEvent.text }, function(newState) {
console.log('Changed State');
console.log('searchString = ' + this.state.searchString);
}.bind(this));
React Documentation中也提到了。
美好的一天。我有以下问题:我有一个 class 计算器,它会在单击按钮时更改 firstOperand 参数的状态。但是状态不会立即改变,只有当我再点击一个按钮时它才会改变 firstOperand 的状态。结果是延迟了 1 个操作:我点击了 1 - 指标没有改变,我点击了 2 - 指标变成了 1,我点击了 5 - 指标变成了 12,等等。 这是我的部分代码:
var Indicator = React.createClass({
render: function () {
return (
<div className="calc-indicator">
<input id="indicator" type="text" maxLength="20" size="20" value={this.props.value}/>
</div>
);
}
});
var Button = React.createClass({
render: function () {
return (
<div className="nav-button">
<button type="button" id={this.props.identifier} onClick={this.props.clickHandler}>
{this.props.digit}
</button>
</div>
);
}
});
var Calculator = React.createClass({
setFirstOperand: function (value) {
this.setState(
{
firstOperand: value
}
);
if (isDebug) {
console.log("First operand state is set to " + value + ".");
}
},
setSecondOperand: function (value) {
this.setState(
{
secondOperand: value
}
);
},
changeIndicator: function (value) {
if (isDebug) {
console.log("///Change indicator method is working///");
console.log("change indicator parameter is " + value);
console.log("first operand is " + this.state.firstOperand);
console.log("second operand is " + this.state.secondOperand);
console.log("operation is " + this.state.operation);
}
if (!value) { // if value hasn't been gotten
value = '';
if (this.state.firstOperand) {
value += this.state.firstOperand;
} else {
value = '0';
}
if (this.state.operation) {
value += this.state.operation;
}
if (this.state.secondOperand) {
value += this.state.secondOperand;
}
}
this.setState(
{
value: value
}
);
if (isDebug) {
console.log("indicator is changed to " + value);
console.log("/////////////////////////////////////");
}
},
getInitialState: function () {
calculator = this;
return {
firstOperand: null,
secondOperand: null,
operation: null,
divisionByZero: false,
value: '0'
};
},
cipherClicked: function (event) {
if (this.state.divisionByZero) {
this.setDivisionByZero(false);
}
var newValue = event.target.innerHTML;
var firstValue = this.state.firstOperand;
var secondValue = this.state.secondOperand;
var operation = this.state.operation;
if (operation) {
if (secondValue) {
secondValue = secondValue + newValue;
} else {
secondValue = newValue;
}
if (isDebug) {
console.log("Second operand state is setting to " + secondValue + ".");
}
this.setSecondOperand(secondValue);
} else {
if (firstValue) {
firstValue = firstValue + newValue;
} else {
if (newValue != 0) { // if indicator contains 0 and you have tried to add one 0 more
firstValue = newValue;
}
}
if (isDebug) {
console.log("First operand state is setting to " + firstValue + ".");
}
this.setFirstOperand(firstValue);
setOperand(firstValue);
}
if (isDebug) {
console.log("Calling changeIndicator function.");
}
this.changeIndicator();
},
render: function () {
return (
<div id="calculator">
<table>
<tr>
<td colSpan="4">
<Indicator value={this.state.value} />
</td>
</tr>
<tr>
<td>
<Button identifier="MC" digit="MC" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="MR" digit="MR" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="M+" digit="M+" clickHandler={this.memoryNavigationClicked}/>
</td>
<td>
<Button identifier="M" digit="M" clickHandler={this.memoryNavigationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="BS" digit="BS" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="CL" digit="CL" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="C" digit="C" clickHandler={this.editNavigationClicked}/>
</td>
<td>
<Button identifier="negate" digit="+-" clickHandler={this.negateClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="7" digit="7" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="8" digit="8" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="9" digit="9" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="divide" digit="/" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="4" digit="4" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="5" digit="5" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="6" digit="6" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="multiply" digit="*" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="1" digit="1" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="2" digit="2" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="3" digit="3" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="minus" digit="-" clickHandler={this.operationClicked}/>
</td>
</tr>
<tr>
<td>
<Button identifier="0" digit="0" clickHandler={this.cipherClicked}/>
</td>
<td>
<Button identifier="dot" digit="." clickHandler={this.dotClicked}/>
</td>
<td>
<Button identifier="eq" digit="=" clickHandler={this.operationClicked}/>
</td>
<td>
<Button identifier="plus" digit="+" clickHandler={this.operationClicked}/>
</td>
</tr>
</table>
</div>
);
}
});
React.render(<Calculator />, document.body);
</script>
</body>
</html>
根据我的 React Native 回答 setState
可以是异步操作,而不是同步操作。这意味着状态更新可以一起批处理,而不是立即完成,以获得性能提升。如果你真的需要在状态真正更新后做一些事情,有一个回调参数:
this.setState({ searchString: event.nativeEvent.text }, function(newState) {
console.log('Changed State');
console.log('searchString = ' + this.state.searchString);
}.bind(this));
React Documentation中也提到了。