簡體   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