函数未传递给Button

时间:2017-09-30 10:53:04

标签: javascript reactjs relaymodern

我知道JavaScript的范围,但可能我完全不理解它们,因为这段代码不起作用。

此代码使用React和Relay Modern框架。

有2个按钮,第一个在queryRender内,后者传递到Relay Modern QueryRenderer,第二个按钮传递到后面(参见函数render)。第二个是工作,第一个不执行clickTest功能。 (这是实际代码的简化版)

class Candidates extends Component {
  static propTypes = {
    viewer: PropTypes.object
  }

  constructor (props) {
    super(props)
    this.clickTest = this.clickTest.bind(this)
  }

  clickTest () {
    console.log('click works')
  }    

  queryRender ({error, props}) {
    if (error) {
      return <pre>{error.message}</pre>
    } else if (props) {
      return (
        <div>
          <Button onClick={this.clickTest}>this DOESN'T work</Button>
        </div>
      )
    }
    return <Loader active>Loading...</Loader>
  }

  render () {
    return (
      <div>
        <QueryRenderer
          environment={environment}
          query={query} 
          render={this.queryRender}
        />
        <Button onClick={this.clickTest}>this works</Button>
      </div>
    )
  }
}

query变量已定义,我只是没有将其包含在摘录中。

当我用匿名的

替换第一个按钮的onClick函数时
<Button onClick={() => this.clickTest()}>this DOESN'T work</Button>

然后我得到这样的错误:Uncaught TypeError:_this2.clickTest不是函数

任何人都可以向我解释为什么这段代码会像它那样表现吗?

3 个答案:

答案 0 :(得分:1)

在javascript中,this的含义不是在创建的函数时确定的,而是在调用时确定的。当QueryRenderer调用您的queryRender函数时,它不知道它需要在您的类的上下文中调用它,因此this将不会引用您认为它所指的内容。

你需要绑定你的queryRender函数,就像你在构造函数中使用clicktest函数一样,或者你需要重新设计queryRender所以它不需要对this的引用。

答案 1 :(得分:1)

扩展Artur和Nicholas&#39;答案,您需要bind()这个或使用箭头函数来确保this指的是组件本身。你已经有了bind方法,这里是箭头函数的一个例子,它摆脱了绑定的需要,因为箭头函数实际上没有绑定这个值,他们使用它们的父节点而不是......

class Candidates extends Component {
  static propTypes = {
    viewer: PropTypes.object
  }

  constructor (props) {
    super(props)
    this.clickTest = this.clickTest.bind(this)
  }

  clickTest () {
    console.log('click works')
  }    

  queryRender = ({error, props}) => {
    if (error) {
      return <pre>{error.message}</pre>
    } else if (props) {
      return (
        <div>
          <Button onClick={this.clickTest}>this DOESN'T work</Button>
        </div>
      )
    }
    return <Loader active>Loading...</Loader>
  }

  render () {
    return (
      <div>
        <QueryRenderer
          environment={environment}
          query={query} 
          render={this.queryRender}
        />
        <Button onClick={this.clickTest}>this works</Button>
      </div>
    )
  }
}

答案 2 :(得分:0)

箭头功能不会创建新范围,其范围是封闭执行上下文,在这种情况下它是QueryRenderer范围内您没有此功能。当您将其作为简单函数传递时,范围将是未定义的,我不知道Button内部的内容。我还没有使用过Rely,也不确定你可以从Rely render方法中引用组件。