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

例如,当将对象的方法作为DOM事件处理程序与vanilla JS一起使用时,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代码中,它并不是作为对象的一部分调用的,而是作为callback传递,然后像任何其他回调一样调用,比如callback()或类似的东西(而不是作为对象的一部分).如果稍微调整代码,使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相关问答推荐

将状态向下传递给映射的子元素

Redux查询多个数据库Api reducerPath&

使用JavaScript重新排序行

如何从URL获取令牌?

使用JQuery单击元素从新弹出窗口获取值

在使用HighChats时如何避免Datatables重新初始化错误?

如何将innerHTML字符串修剪为其中的特定元素?

如何在 Select 文本时停止Click事件?

从另一个数组中的对应行/键值对更新数组中的键值对对象

我想将Sitecore搜索面过滤器从多个转换为单个

第一项杀死下一项,直到数组长度在javascript中等于1

如何根据查询结果重新排列日期

JavaScript将字符串数字转换为整数

将Singleton实例设置为未定义后的Angular 变量引用持久性行为

重新渲染过多(&Q).REACT限制渲染次数以防止无限循环.使用REACT下拉菜单时

正则表达式以确定给定文本是否不只包含邮箱字符串

Firebase函数中的FireStore WHERE子句无法执行

如何在css中裁剪成一定Angular 的圆的一部分,而不需要复杂的多边形

如何在底部重叠多个div?

如何将缓冲区数组转换回音频