我正在阅读Forms文档的reactjs部分,并尝试使用此代码来演示onChange
用法(JSBIN)。
var React= require('react');
var ControlledForm= React.createClass({
getInitialState: function() {
return {
value: "initial value"
};
},
handleChange: function(event) {
console.log(this.state.value);
this.setState({value: event.target.value});
console.log(this.state.value);
},
render: function() {
return (
<input type="text" value={this.state.value} onChange={this.handleChange}/>
);
}
});
React.render(
<ControlledForm/>,
document.getElementById('mount')
);
当我更新浏览器中的<input/>
值时,console.log
回调中的第二个handleChange
会打印与第一个value
相同的console.log
,为什么我无法在this.setState({value: event.target.value})
回调范围内看到handleChange
的结果?
答案 0 :(得分:517)
来自React&#39; documentation:
setState()
不会立即改变this.state
但会创建一个 待定状态转换。在调用此文件后访问this.state
方法可以返回现有值。没有 保证同步操作setState
和电话可能 为获得业绩增长而受到批评。
如果您希望在状态更改发生后执行某项功能,请将其作为回调传递。
this.setState({value: event.target.value}, function () {
console.log(this.state.value);
});
答案 1 :(得分:41)
正如React文档中所述,无法保证同步触发setState
,因此您的console.log
可能会在更新之前返回状态。
Michael Parker提到在setState
内传递回调。在状态更改后处理逻辑的另一种方法是通过componentDidUpdate
生命周期方法,这是React docs中推荐的方法。
通常我们建议使用componentDidUpdate()代替这种逻辑。
当可能连续setState
被触发时,这个特别有用,并且您希望在每次状态更改后触发相同的函数。您可以将函数放在setState
内,而不是向每个componentDidUpdate
添加回调,如果需要,可以在内部使用特定逻辑。
// example
componentDidUpdate(prevProps, prevState) {
if (this.state.value > prevState.value) {
this.foo();
}
}
答案 2 :(得分:10)
您可以尝试使用ES7异步/等待。例如,以您的示例为例:
handleChange: async function(event) {
console.log(this.state.value);
await this.setState({value: event.target.value});
console.log(this.state.value);
}
答案 3 :(得分:6)
当心反应生命周期方法!
我工作了几个小时才发现,每getDerivedStateFromProps
之后都会调用setState()
。
答案 4 :(得分:0)
async-await
语法非常适合以下内容...
changeStateFunction = () => {
// Some Worker..
this.setState((prevState) => ({
year: funcHandleYear(),
month: funcHandleMonth()
}));
goNextMonth = async () => {
await this.changeStateFunction();
const history = createBrowserHistory();
history.push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}
goPrevMonth = async () => {
await this.changeStateFunction();
const history = createBrowserHistory();
history.push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}
答案 5 :(得分:0)
简单地放置-this.setState({data:value})是异步的 这意味着它会移出调用堆栈,而只会返回 除非解决了,否则将调用“呼叫堆栈”。
请阅读有关事件循环的详细信息,以了解JS中的异步性质以及更新为什么需要时间-
https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4
因此-
this.setState({data:value});
console.log(this.state.data); // will give undefined or unupdated value
,因为更新需要时间。 要实现上述过程-
this.setState({data:value},function () {
console.log(this.state.data);
});