为什么调用react setState方法不会立即改变状态?

本文翻译自:Why calling react setState method doesn't mutate the state immediately?

I'm reading Forms section of documentation and just tried this code to demonstrate onChange usage ( JSBIN ). 我正在阅读文档的Forms部分,只是尝试了这段代码来演示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')
);

When I update the <input/> value in the browser, the second console.log inside the handleChange callback prints the same value as the first console.log , Why I can't see the result of this.setState({value: event.target.value}) in the scope of handleChange callback? 当我在浏览器中更新<input/>值时, handleChange回调内的第二个console.log与第一个console.log打印相同的value ,为什么我看不到this.setState({value: event.target.value})handleChange回调的范围内?


#1楼

参考:https://stackoom.com/question/25a3a/为什么调用react-setState方法不会立即改变状态


#2楼

From React's documentation : 从React的文档中

setState() does not immediately mutate this.state but creates a pending state transition. setState()不会立即使this.state突变,但会创建一个挂起的状态转换。 Accessing this.state after calling this method can potentially return the existing value. 调用此方法后访问this.state可能会返回现有值。 There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains. 无法保证对setState的调用的同步操作,并且可能会为提高性能而批量调用。

If you want a function to be executed after the state change occurs, pass it in as a callback. 如果要在状态更改后执行函数,请将其作为回调传递。

this.setState({value: event.target.value}, function () {
    console.log(this.state.value);
});

#3楼

As mentioned in the React documentation, there is no guarantee of setState being fired synchronously, so your console.log may return the state prior to it updating. 正如React文档中提到的那样,不能保证setState被同步触发,因此console.log可能会在更新之前返回状态。

Michael Parker mentions passing a callback within the setState . 迈克尔·帕克(Michael Parker)提到在setState中传递回调。 Another way to handle the logic after state change is via the componentDidUpdate lifecycle method, which is the method recommended in React docs. 状态更改后处理逻辑的另一种方法是通过componentDidUpdate生命周期方法,这是React文档中推荐的方法。

Generally we recommend using componentDidUpdate() for such logic instead. 通常,我们建议对这种逻辑使用componentDidUpdate()代替。

This is particularly useful when there may be successive setState s fired, and you would like to fire the same function after every state change. 当可能会连续触发setState ,并且您希望在每次状态更改后触发相同的函数时,此功能特别有用。 Rather than adding a callback to each setState , you could place the function inside of the componentDidUpdate , with specific logic inside if necessary. 您可以将函数放置在componentDidUpdate内部,而不是在每个setState添加回调,如有必要,可以在其中放置特定的逻辑。

// example
componentDidUpdate(prevProps, prevState) {
  if (this.state.value > prevState.value) {
    this.foo();  
  }
}

#4楼

Watch out the react lifecycle methods! 注意反应生命周期方法!

I worked for several hours to find out that getDerivedStateFromProps will be called after every setState() . 我工作了几个小时才发现,每个setState()之后都会调用getDerivedStateFromProps

😂 😂


#5楼

You could try using ES7 async/await. 您可以尝试使用ES7异步/等待。 For instance using your example: 例如,使用您的示例:

handleChange: async function(event) {
    console.log(this.state.value);
    await this.setState({value: event.target.value});
    console.log(this.state.value);
}

#6楼

async-await syntax works perfectly for something like the following... 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}`);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值