我正在阅读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/>值时,handleChange回调中的第二个console.log打印与第一个console.log相同的值,为什么我看不到这个结果。setState({value: event.target.value})在handleChange回调的范围?


当前回答

来自React的文档:

setState()不会立即改变它。状态,但创建了 挂起状态转换。访问。调用后的状态 方法可能返回现有的值。没有 保证调用setState和调用may的同步操作 批处理以获得性能提升。

如果希望在状态改变发生后执行函数,可以将其作为回调传入。

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

其他回答

您可以尝试使用ES7 async/await。举个例子:

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

有时这种问题会发生在状态中。 对于钩子,你应该使用useEffect钩子,如下所示-

const [fruit, setFruit] = useState('');
 
setFruit('Apple');
useEffect(() => {
  console.log('Fruit', fruit);
}, [fruit])

这救了我的一天,希望会帮助你!!

正如React文档中提到的,没有保证setState被同步触发,所以你的console.log可能会在更新之前返回状态。

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

通常,我们建议对这种逻辑使用componentDidUpdate()。

当可能连续触发了setStates,并且您希望在每次状态更改后都触发相同的函数时,这特别有用。您可以将函数放置在componentDidUpdate中,而不是向每个setState添加回调,如果需要的话,在其中使用特定的逻辑。

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

来自React的文档:

setState()不会立即改变它。状态,但创建了 挂起状态转换。访问。调用后的状态 方法可能返回现有的值。没有 保证调用setState和调用may的同步操作 批处理以获得性能提升。

如果希望在状态改变发生后执行函数,可以将其作为回调传入。

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

React会对不同的set状态调用进行洗浴,这样它就可以确定重新呈现网站的最优策略。

假设您有一个应用程序,其中有许多不同的组件。也许,通过单击一个按钮,您正在更新多个组件的状态,而不仅仅是当前组件。在这种情况下,React并不想完全隔离,而是独立地执行所有这些不同的更新。

React想要弄清楚它是否可以将所有这些更新堆叠在一起,也许有一种更优的更新这些组件的方式,这样它就更性能。这就是React在幕后所做的事情。因此,set state调用是异步调用。