繁体   English   中英

函数未传递给Button的原因是什么

[英]What is the reason that function is not passed to a Button

我知道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>

然后我得到这样的错误:未捕获的TypeError:_this2.clickTest不是一个函数

谁能向我解释为什么这段代码会如此运行?

在JavaScript中,的含义this创建函数时没有确定,而是被调用时。 当QueryRenderer调用您的queryRender函数时,它不知道需要在您的类的上下文中调用它,因此this将不会指向您认为的对象。

你要么需要绑定你的queryRender功能,就像你与你的clicktest功能在构造函数中做什么,或者你需要重新设计queryRender所以它并不需要参考this

要扩展Artur和Nicholas的答案,您要么需要bind()这个,要么使用箭头函数来确保this是指组件本身。 您已经使用了bind方法,这是arrow函数的en示例,该示例摆脱了绑定的需要,因为arrow函数实际上并不绑定此值,而是使用其父范围。

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>
    )
  }
}

Arrow函数不会创建新的作用域,它的作用域包含执行上下文,在这种情况下,它是QueryRenderer作用域,而您没有此功能。 当您将其作为简单函数传递时,范围将是不确定的或不确定的,我不知道Button在做什么。 我没有使用过Rely,并且不确定您可以从Rely渲染方法中引用组件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM