在哪里可以找到关于为什么在 React 中将对象方法分配为 DOM 事件处理程序时未定义“this”上下文的文档?

Where can I find documentation on why `this` context is undefined when assigning object method's as DOM event handlers in React?

提问人:crosen9999 提问时间:6/20/2022 更新时间:6/20/2022 访问量:29

问:

似乎 React 组件改变了 DOM 事件处理程序中分配方式的行为,但我找不到任何详细说明此行为的文档。this

例如,当使用对象的方法作为 vanilla JS 的 DOM 事件处理程序时,上下文仍为对象:this

function SomeClass() {}
SomeClass.prototype.showThis = function() { console.log(this) };
let o = new SomeClass();
<button onclick="o.showThis()">Show "this"</button>

然而,React 会改变这种行为,使上下文变得未定义:this

function SomeClass() {}
SomeClass.prototype.showThis = function() { console.log(this) };
let o = new SomeClass();

function App() {
  return (
       <button onClick={o.showThis}>Show this</button>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

解释这一点的文档在哪里?(我可以推测为什么会发生这种情况,但想知道 React 文档中在哪里涵盖了这一点。

javascript reactjs dom-events 这个

评论

2赞 Pointy 6/20/2022
React 没有这样做。 传递对要用作处理程序的函数的引用,但与对象的关系将丢失。这是正常的 JavaScript 行为。{o.showThis}o
0赞 crosen9999 6/20/2022
我提供的普通 JavaScript 示例不会导致这种情况。使用对象的方法执行此操作的普通 JavaScript 示例示例是什么?
0赞 Pointy 6/20/2022
这是因为在这种情况下,将围绕您传递的字符串构造一个函数。

答:

2赞 CertainPerformance 6/20/2022 #1

这对 React 来说并没有什么特别之处。这是因为,使用内联处理程序时,函数被调用的那一刻,它就作为对象的一部分被调用:

onclick="o.showThis()"
         ^ object
                   ^^ invocation

但在 React 代码中,它不是作为对象的一部分被调用的——而是作为回调传递的,然后像任何其他回调一样被调用——like 或类似的东西(而不是作为对象的一部分)。如果对代码进行非常轻微的调整,以便将 作为对象的一部分调用,它将显示与内联处理程序相同的行为:o.showThiscallback()showThis

onClick={() => o.showThis()}
               ^ object
                         ^^ invocation

function SomeClass() {}
SomeClass.prototype.showThis = function() { console.log(this) };
let o = new SomeClass();

function App() {
  return (
       <button onClick={() => o.showThis()}>Show this</button>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

因此,React 没有特别解释它——它是底层 JavaScript 的行为。

如果函数不是作为对象的一部分调用的,并且您处于严格模式,则同样会进入内联处理程序。undefined

'use strict';

function SomeClass() {}
SomeClass.prototype.showThis = function() {
  console.log(this)
};
const o = new SomeClass();

const theFn = o.showThis;
<button onclick="theFn()">Show "this"</button>

评论

0赞 crosen9999 6/20/2022
“但在 React 代码中,它不是作为对象的一部分被调用的——相反,o.showThis 是作为回调传递的。”我想我的问题是,为什么在 React 中它作为回调传递的事实不符合 React 特定的东西,并且 React 文档应该解释?我怀疑你是说这很明显,这一定是发生的——我怀疑这是基于行为——但我不清楚为什么这是给定的。
1赞 CertainPerformance 6/20/2022
因为 它不存在于它作为对象的一部分被引用的位置,所以它必须是一个回调 - 就像放入未连接到对象的不同变量名称中一样。同样的事情也适用于任何图书馆。,如果它曾经调用,则不会用 of 调用它,因为调用它的地方没有引用 。现在,如果它在它是对象的一部分时被调用,那将是一个不同的故事 - 但事实并非如此。()const theFn = o.showThis;showThisosomeLibraryFunction(someObject.someMethod)someMethodthissomeObjectsomeObject