为什么事件处理程序需要引用而不是调用?
在React tutorial,它说为什么事件处理程序需要引用而不是调用?
做
onClick={alert('click')}
会立即发出警告,而不是在单击按钮时。
class Square extends React.Component {
render() {
return (
<button className="square" onClick={() => alert('click')}>
{this.props.value}
</button>
);
}
}
不过,我不明白为什么那会是......任何人都可以澄清这对我好吗?为什么不能作为处理程序传递函数调用?
当你做onClick={alert("click")}
这将调用alert
函数并将返回值(undefined
)分配给onClick
属性。所以,React看到的是onClick={undefined}
并说:好吧,那不是一个函数,为什么我会添加这样一个处理程序?
想要传递给onClick
的是函数,而不是undefined
。
因此,你必须做的:onClick={myFunction}
其中myFunction
可以() => alert("...")
正如你所说,或者您可以使用bind
创建类似的功能:
onClick={alert.bind(window, "click")}
bind
将回一个新功能这将使用"click"
参数在内部调用alert
函数。
类似的情况是当你做setTimeout(() => alert("after 1 second"), 1000)
。 setTimeout
需要一个功能。如果你做setTimeout(alert("..."), 1000)
,确实会调用alert
,但setTimeout
将接收第一个参数undefined
(这就是alert
返回的结果)。
相反,如果你有返回功能,功能,将工作:
// This will be called first and will return a function
const sayHelloTo = name => {
// This will be the function passed to `setTimeout`
return() => alert(`Hello ${name}`);
};
setTimeout(sayHelloTo("Alice"), 1000);
您可以使用它以同样的方式为onClick
啄:
onClick={sayHelloTo("Alice")}
这是关于背景中发生的事情的一个非常小的例子(这只是一个概念证明,我确定它实际上发生的是更好的方式这一个):
const elm = {
onClick: null,
// The click method can be invoked manually
// using `elm.click()` or is natively invoked by the browser
click() {
if (typeof this.onClick === "function") {
this.onClick();
}
}
};
// If you do:
elm.onClick = alert("click"); // this calls the alert, and returns undefined
elm.onClick === undefined // true
// But when doing:
elm.onClick =() => alert("click");
typeof elm.onClick // "function"
elm.click(); // this will call the alert
当你有一个事件处理程序它必须是一个函数引用,而不是一个函数调用。这是因为在执行处理程序的内部,处理程序在被调用之前首先被评估为。使用内联JSX表达式(例如传递事件处理程序prop时),在调用处理函数之前声明组件时,表达式为评估为。
因此,如果您传入诸如alert('click')
之类的调用,它将在进行评估时发出警报。当事件被触发并且处理程序被调用时,它将尝试调用返回值alert
(这是未定义的) - 不好。相反,你需要一个函数引用,当它被评估时给你一个可调用的函数,然后调用它作为处理函数。
拿这个伪代码为例:
function on(event, handler) {
//some event listener function that runs the handler when event happens
//then we call handler when the event happens:
handler();
}
试想一下,如果我们调用的功能on('click', alert('test'))
,然后alert('test')
会进行评估和返回值将作为处理函数,这是不确定的传递。那么你会试图拨打undefined()
,不好。因此,您必须传递函数引用,即对可调用函数的引用。
谢谢!非常好的解释! – coffeeak
'alert('click')'是一个函数调用。 React会读取它并立即执行它。您应该将引用传递给命名函数。所以,'this.myFunction'而不是'this.myFunction()'。或者,您可以引用一个匿名函数,这就是您在原始文章中输入的内容。 – glhrmv