与正常调用函数相比,为什么使用箭头函数会在 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
;届时,状态已设置,因此它会记录新值。
采取以下反应代码
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
;届时,状态已设置,因此它会记录新值。