![](/img/trans.png)
[英]why are we binding 'this' keyword for event handlers in react class components?
[英]'this' context different for event handlers in function vs class react components
为什么'this'(上下文)会根据我在反应中使用功能组件还是 class 组件而有所不同? 我了解绑定的工作原理,并且我的处理程序将采用 onclick 处理程序的上下文(或者它在 onclick 中使用),但我不明白为什么这两种情况的值不同。 功能组件打印 window object 而 class 组件打印未定义。
如何定义合成 onclick 事件? 它的背景是什么? 它的回调有什么作用?
export default function App() {
const handleClick = function () {
console.log(this);
};
return (
<div className="App">
<button onClick={handleClick}>HandleClick Functional</button>
<Toggle />
</div>
);
}
class Toggle extends React.Component {
handleClick() {
console.log(this);
}
render() {
return <button onClick={this.handleClick}>HandleClick Class</button>;
}
}
代码框链接: https://codesandbox.io/s/onclick-context-test-ievog6?file=/src/App.js
TL;DR - 这看起来像 CodeSandbox 的一个错误。 您的 React function 组件代码最终以非严格模式运行,这导致您的this
值默认为全局 object 而不是应为的undefined
。
这种行为很奇怪。 但就像qrsngky在上面的评论中正确指出的那样,问题主要与严格模式有关,并且是 CodeSandbox 如何进行错误处理的结果。 下面我概述了我对您的代码为何如此运行的观察。
使用function
关键字声明的函数有自己的this
值(它们自己的“this 绑定”)。 如何确定this
值取决于 function 的执行方式。 .call( .call()
和.apply()
等方法能够为它们执行的 function 设置this
值。
在严格模式代码中,使用fn.apply(undefined)
会导致执行 function fn
并将fn
中的this
值设置为undefined
。 但是,在非严格模式代码中,使用fn.apply(undefined)
会导致this
值设置为全局 object ,在浏览器中为window
object。 当 React 调用您的onClick
处理程序 function ( func
) 时,它通过执行func.apply(context, ...)
来调用它,并将context
设置为undefined
(您可以通过调试器看到这一点):
此时,您可能会认为您的代码在任何地方都没有使用"use strict"
指令,因此当您的 function 使用this
of undefined
调用时,它默认为全局 object window
。 但是,它并不像那样简单;)。 虽然看起来您的任何代码都没有在严格模式下运行,但实际上它被归类为严格模式代码。 那是因为ES6 模块(您编写反应代码的内容) 会自动在 strict-mode 下运行。 同样, 类也自动以严格模式运行。 所以这就引出了一个问题,即为什么你的代码显示window
那么你的代码是否真的应该在严格模式下运行。
编写 React 代码时,需要将其转换为浏览器可以理解和执行的代码。 似乎发生的事情是,当您的反应代码被转译时,CodeSandbox 在您的反应代码周围添加了一个try-finally 包装器(您可以使用禁用源映射的调试器看到这一点):
try {
"use strict";
...
function App() {
const handleClick = function() {
console.log(this);
}
}
...
} finally {
...
}
我们可以看到 CodeSandbox 尝试将您的代码包装在 try-finally 块中,其中try
块以“严格模式”运行,以尝试匹配最初编写代码的 ES6 模块自动应用的相同严格模式行为。但是,在与 function 无关的块{}
中应用"use strict"
对代码的严格性没有影响(有关严格模式的规则,请参见 此处)。 因此,CodeSandbox 应用的 try-finally 包装器最终会以非严格/草率模式运行您的代码。 当 React 使用undefined
调用您的 onClick 处理程序时,这将导致this
为window
。
另一方面,您的class
仍然按预期工作,因为在转译的代码中它仍然是class
,因此围绕类的严格模式行为仍然存在,因此您会看到undefined
的预期。
但是,在使用 React 功能组件时,您不需要参考this
,而是可以使用诸如useState()
类的钩子来管理诸如 state 之类的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.