箭头函数 ReactJS 中的 This 上下文

This context in arrow function ReactJS

我有一个像这样的 React 组件。

import React, { PropTypes, Component } from 'react';
import { Accordion, Panel, PanelGroup, Table } from 'react-bootstrap';


const FormCell = ({ data }) => (
  <div>
    <a className="pdf-name" onClick={this.doSomething}>{data.item.extension.nameCodeDes}</a>
  </div>
);

class Docs extends Component {
  constructor(props) {
    super(props);
    this.doSomething= this.doSomething.bind(this);
  }

  doSomething() {
    setTimeout(() => {
      console.log("here we are");
    })
  }

  // ...
}

Docs.defaultProps = {
  tableData: null,
  cols: null,
  metaData: {
    documentsColumnMetaData: [
      {
        displayName: 'Policy/Account',
        columnComponent: {
          component: FormCell,
          actions: [],
        },
      },
    ],
  },
};

export default Docs;

this.doSomething 在开发工具中被转译为 undefined.doSomething。我收到一个错误 Cannot read 属性 'downloadDocument' of undefined。有人可以让我知道我在这里缺少什么吗? P.S FormCell 所做的比发布的更多。为了简单起见,我减少了代码

箭头函数没有 this,而是 this 落到上层作用域。我不确定为什么在这种特定情况下它是未定义的,但这不是您通常想要进入的领域。看看这段代码,我猜 this 会是全局对象,但也许引用 this 的顶级箭头函数应该以这种方式运行。

如果要绑定函数,请改为使用 function 关键字定义它。

function FormCell({ data }) {
    return <div>
        <a className="pdf-name" onClick={this.doSomething}>{data.item.extension.nameCodeDes}</a>
    </div>;
}

扩展我上面的评论...

您的代码示例中有两个不同的组件:FormCellDocs。它们之间似乎没有任何关系,除了你指的是 FormCell 组件中未定义的 this.doSomething 函数,它恰好具有相同的名称作为 doSomething 函数声明为 Docs 组件上的方法。这让我认为它们应该是相同的功能。

所以,从这个假设出发...

FormCell中提到的this.doSomething函数应该是指FormCell.doSomething函数。毕竟,this.doSomething 被调用 呈现 FormCell 组件的函数中 - 它应该引用 FormCell 然后。但是您还没有在 FormCell 组件上定义 doSomething 函数,因此它没有任何可引用的内容(您应该得到 "doSomething is not a function" 或 "doSomething is undefined" 错误) .

如果您打算让 FormCell 中的 this.doSomething 引用 Docs 组件实例上的 doSomething 函数,那么您将需要将该函数作为道具传递给 FormCell 组件。

这看起来你做错了,但我还是直接回答你的问题。这里的问题是您在 Docs 之外定义 FormCell,但您希望 thisDocs 的实例。你能做的是

改为:

const FormCell = ({ data, doSomething }) => (
    <div>
        <a className="pdf-name" onClick={doSomething}>{data.item.extension.nameCodeDes}</a>
    </div>
);

然后我假设您在 Docs 组件中省略了一些代码,看起来像这样

const ColumnComponent = this.props.metaData.documentsColumnMetaData[ 0 ].columnComponent.component;
return <ColumnComponent data={ someData } doSomething={ this.doSomething } />;

注意我是如何添加 doSomething={ this.doSomething } 的。这将允许您将 doSomething 方法作为道具传递给 FormCell 组件。