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

IT技术 javascript reactjs react-jsx
2020-12-31 16:26:33

我正在阅读表格部分文档并尝试使用此代码来演示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回调?

6个回答

来自 React 的文档

setState()不会立即变异,this.state而是创建一个挂起的状态转换。this.state调用此方法后访问可能会返回现有值。无法保证调用的同步操作,setState并且可能会批处理调用以提高性能。

如果您希望在发生状态更改后执行某个函数,请将其作为回调传入。

this.setState({value: event.target.value}, function () {
    console.log(this.state.value);
});
好答案。我需要做的观察是小心使用 valueLink。如果您不必格式化/屏蔽输入,它会很好用。
2021-02-25 16:26:33
您可能还想查看componentDidUpdate. 它会在状态改变后被调用。
2021-02-26 16:26:33
...为什么?有人可以证明这一点吗?
2021-03-02 16:26:33
快速提问,如果我可以,我看到一旦我们将我们需要的函数作为回调传递给 setState ,我希望在调用 render() 之前首先执行该函数。但我看到顺序是 setState() -> render() -> setStates' callback() 。这是正常的吗?如果我们想根据我们在回调中所做的事情来控制我们的渲染怎么办?应该组件更新
2021-03-06 16:26:33
更改组件的状态将始终触发重新渲染,除非其中有shouldComponentUpdate其他指定的行为在您传递给setState您希望在重新渲染之前发生的回调中,您到底想做什么?
2021-03-08 16:26:33

正如 React 文档中提到的,无法保证setState同步触发,因此您console.log可能会在更新之前返回状态。

Michael Parker 提到在setState. 另一种处理状态更改后逻辑的componentDidUpdate方法是通过生命周期方法,这是 React 文档中推荐的方法。

通常我们建议使用 componentDidUpdate() 来代替这种逻辑。

这在可能会连续setState触发 s时特别有用,并且您希望在每次状态更改后触发相同的函数。setState您可以将函数放置在 中,而不是向 each 添加回调,componentDidUpdate如有必要,可以在其中包含特定逻辑。

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

您可以尝试使用 ES7 异步/等待。例如使用您的示例:

handleChange: async function(event) {
    console.log(this.state.value);
    await this.setState({value: event.target.value});
    console.log(this.state.value);
}
如果当我想更新某个状态然后等待它更新时总是使用 await ,这会影响性能吗?如果我将多个 await setState 放在一个链中,它会在每个 setState 更新后呈现吗?还是在最后一次 setState 更新之后?
2021-02-25 16:26:33
另一个答案是关于在 setState() 中使用回调。我想我把它放在这里是为了那些不适用回调用例的人。例如,当我自己遇到这个问题时,我的用例涉及在设置后立即更新状态的开关案例。因此,使用 async/await 优于使用回调。
2021-03-06 16:26:33
您的回答与其他高质量的回答有何不同?
2021-03-08 16:26:33

注意 react 生命周期方法!

我工作了几个小时才发现getDerivedStateFromProps每个setState().

😂

你的评论拯救了我的一天 :D
2021-03-01 16:26:33

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}`);
}