箭头函数ReactJS中的此上下文

时间:2016-12-16 00:08:27

标签: javascript reactjs ecmascript-6 arrow-functions

我有一个看起来像这样的反应组件。

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 in dev工具。我得到一个错误无法读取未定义的属性'downloadDocument'。有人可以让我知道我在这里缺少什么吗? P.S FormCell更多地发布了所发布的内容。为简单起见,我减少了代码

3 个答案:

答案 0 :(得分:0)

箭头功能没有this,而this则落在上限范围内。我不确定为什么在这个特定的情况下它没有被定义,但这不是你想要正常的领域。看看这段代码,我猜想this将是全局对象,但是引用this的顶级箭头函数可能会以这种方式运行。

如果要绑定该功能,请改为使用function关键字进行定义。

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

答案 1 :(得分:0)

扩展我上面的评论......

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

所以,按照这个假设工作......

Docs中提及的this.doSomething函数应引用FormCell函数。毕竟,FormCell.doSomething被称为来自呈现this.doSomething组件的函数 - 它应该引用FormCell。但是你还没有在FormCell组件上定义doSomething函数,所以它没有任何内容可供引用(你应该得到“doSomething不是函数”或“doSomething is undefined”)误差)。

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

答案 2 :(得分:0)

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

将其更改为:

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组件。