在React tutorial中,它说
执行
onClick={alert('click')}
会立即发出警报,而不是点击按钮时。
class Square extends React.Component {
render() {
return (
<button className="square" onClick={() => alert('click')}>
{this.props.value}
</button>
);
}
}
然而,我无法理解为什么会这样......有人可以为我澄清这个吗?为什么不能将函数调用作为处理程序传递?
答案 0 :(得分:11)
执行onClick={alert("click")}
时,将调用alert
函数并将返回值(undefined
)分配给onClick
属性。那么,React看到的是onClick={undefined}
并说:嗯,这不是一个函数,为什么我会添加这样的处理程序?
您希望传递给onClick
的是一个函数,而不是undefined
。
因此,您必须执行:onClick={myFunction}
,如您所提及的,myFunction
可以是() => alert("...")
,或者您可以使用bind
创建类似的功能:
onClick={alert.bind(window, "click")}
bind
将返回 新函数,它将在内部使用alert
参数调用"click"
函数。
类似的情况是setTimeout(() => alert("after 1 second"), 1000)
。 setTimeout
期望一个功能。如果您执行setTimeout(alert("..."), 1000)
,则会调用alert
,但setTimeout
将作为第一个参数undefined
收到(这是alert
返回的内容)。< / p>
相反,如果你有一个返回一个函数的函数,那么它将起作用:
// 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
答案 1 :(得分:4)
当你有一个事件处理程序时,它必须是一个函数引用,而不是一个函数调用。这是因为在内部执行处理程序时,处理程序首先被评估,然后才能被调用。使用内联JSX表达式(例如传递事件处理程序prop时),在调用处理程序之前,在声明组件时,表达式为 evaluate 。
因此,如果您传入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()
,不好。因此,您必须传递函数引用,即对可调用函数的引用。