setState(...,callback)在设置状态之前调用callback

时间:2016-11-03 04:00:16

标签: reactjs

我经常写这样的代码(重复使用):

function doSomething() {
  // I do something with this.state.MyVar
}

function buttonClicked(e) {
  this.setState({MyVar: e.target.value}, this.doSomething());
}

function otherEvent(e) {
  this.setState({MyVar: e.target.value}, this.doSomething());
}

一旦调用doSomething(),该值与e.target.value的值不同并不罕见。似乎在状态更新后实际上没有发生回调吗?

注意,这总是有效:

function doSomething(value) {
  // I do something with value
}

function buttonClicked(e) {
  this.setState({MyVar: e.target.value});
  this.doSomething(e.target.value);
}

这是在谷歌浏览器中,以及最新版本的ReactJS。

1 个答案:

答案 0 :(得分:2)

省略括号,因为它们立即执行该函数并将解析后的值(返回值)作为回调传递 - 这是不希望的。回调必须是函数引用而不是调用,因为回调是在内部调用的。使用括号,从而调用函数,它将给出立即执行的错觉:

this.setState({MyVar: e.target.value}, doSomething);
//                                                ^^ No parens!

这样,传递doSomething的引用而不是调用,它将相应地执行。

在许多情况下可以看到这些问题的例子。请考虑以下代码段:

document.getElementById("test").addEventListener("click", foo()); //to demonstrate the common mistake, let's try with parentheses

function foo() {
  console.log("I've been clicked (but not really!)"); 
}
<button id="test">Click me!</button>

你可以看到我们正在向按钮#test添加一个监听器,似乎我们将foo设置为事件处理程序,但实际上它会立即执行,即使我们没有点击它!这是因为当运行JavaScript时,会立即执行foo(),从而在它应该之前记录I've been clicked (but not really!)。由于该函数不返回任何内容,因此它等同于:

document.getElementById("test").addEventListener("click", undefined);

undefined作为事件处理程序传递,因为已解析的值作为事件处理程序传递,并且由于函数没有返回任何内容,因此它是undefined

这可以在这里应用,因为当您为回调传递调用时,实际上是在传递该函数的返回值,因为您调用它。要解决此问题,您需要传递参考