与正常调用函数相比,为什么使用箭头函数会在 React 中提供状态的更新版本?

Why does using an arrow function give the updated version of the state in React in comparison to calling the function normally?

采取以下反应代码

class Foo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {state1: true, state2: false, state3: "hello"}
        this.onClick = this.onClick.bind(this)

    }

    onClick() {
        this.setState({state1: false, state2: true, state3: "goodbye"}, console.log(this.state))
    }

    render() {
        return(
            <button onClick = {this.onClick}></button>
        )
    }
}

ReactDOM.render(<Foo />, document.getElementById('root'));

当我在 setState 的回调中使用 console.log 时,我必须在 React 中单击按钮两次,以便控制台显示正确版本的状态。

但是,如果改为写this.setState({state1: false, state2: true, state3: "goodbye"}, () => console.log(this.state)),添加一个箭头功能,点击一次按钮在控制台输出正确版本的状态。这是为什么?为什么箭头函数在这种情况下会输出不同的行为?

因为 this.setState() 的第二个参数是更新状态时调用的回调。 console.log() 没有 return 功能,它会在您调用 this.setState()

的同时调用

首先计算表达式 console.log(this.state),并将结果值传递给 setState

也就是说,这个

this.setState({state1: false, state2: true, state3: "goodbye"}, console.log(this.state))

可以在不改变其行为的情况下重写为以下内容:

let consoleLogResult = console.log(this.state)
this.setState({state1: false, state2: true, state3: "goodbye"}, consoleLogResult)

在设置之前记录当前状态。

现在,console.log总是returnsundefined,所以上面的consoleLogResult总是undefined。它的行为就像你根本没有传递回调 'function'。


如果您改为传递 () => console.log(this.state),它会评估为一个函数,该函数在 执行状态转换后由 React 调用。

在您的第一个示例中,您这样做:

this.setState({state1: false, state2: true, state3: "goodbye"}, console.log(this.state))

这不是传递一个函数作为第二个参数,它是用 this.state 的当前值计算函数 console.log 并传递它的返回结果(对于 console.log 是始终未定义)作为第二个参数。但是如果你使用 setState 的第二个参数,React 期望它是一个函数,而不是 undefined,所以当状态更新时它实际上不会对 运行 有任何回调

在您的第二个示例中,您实际上传递了一个新函数作为参数,并且一旦该函数被调用(作为回调,由 React,当设置了新状态时),函数 调用console.log;届时,状态已设置,因此它会记录新值。