React 组件似乎改变了 DOM 事件处理程序中 this
的分配方式,但我找不到任何详细说明此行为的文档。
例如,当使用一个对象的方法作为普通 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 文档中对此进行了介绍。)
最佳答案
这对 React 来说没什么特别的。这是因为,使用内联处理程序时,函数被调用的那一刻,它就作为对象的一部分被调用:
onclick="o.showThis()"
^ object
^^ invocation
但在 React 代码中,它不会作为对象的一部分被调用 - 相反,o.showThis
作为回调传递,然后像任何其他回调一样被调用回调 - 就像回调()或类似的东西(而不是作为对象的一部分)。如果您稍微调整代码,以便将 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>
关于javascript - 在哪里可以找到有关在 React 中将对象方法分配为 DOM 事件处理程序时为什么 `this` 上下文未定义的文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72679232/