我经常写这样的代码(重复使用):
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。
答案 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
。
这可以在这里应用,因为当您为回调传递调用时,实际上是在传递该函数的返回值,因为您调用它。要解决此问题,您需要传递参考。