如何在构造函数中绑定一个方法与在React.cloneElement的调用中绑定它不同?

时间:2017-03-06 07:08:49

标签: reactjs

import React , {Component} from 'react'

class App extends Component{
  render(){
    return(
      <Buttons>
        <button value='A'>A</button>
        <button value='B'>B</button>
        <button value='C'>C</button>
      </Buttons>
    )
  }
}


class Buttons extends Component{
  constructor(){
    super()
    this.state= {
      selected: 'none'
    }
  }

  selectItem(selected){
    this.setState( { selected } )
  }

  render(){
    let fn = (child) => (
      React.cloneElement( child , {
          // this only change is the call to bind here  
          onClick: this.selectItem.bind(this , child.props.value)
        } 
      )
    )
    let items = React.Children.map(this.props.children , fn)
    return(
      <div>
        <h3>
          you have selected: {this.state.selected}
        </h3>
        {items}
      </div>
    )
  }
}

export default App
import React , {Component} from 'react'

class App extends Component{
  render(){
    return(
      <Buttons>
        <button value='A'>A</button>
        <button value='B'>B</button>
        <button value='C'>C</button>
      </Buttons>
    )
  }
}


class Buttons extends Component{
  constructor(){
    super()
    this.state= {
      selected: 'none'
    }
    // here I added the binding on the constructor . 
    this.selectItem = this.selectItem.bind(this)
  }

  selectItem(selected){
    this.setState( { selected } )
  }

  render(){
    let fn = (child) => (
      React.cloneElement( child , {
          // this only change is the call to bind here  
          onClick: this.selectItem(child.props.value)
        } 
      )
    )
    let items = React.Children.map(this.props.children , fn)
    return(
      <div>
        <h3>
          you have selected: {this.state.selected}
        </h3>
        {items}
      </div>
    )
  }
}

export default App

在传递给this的回调中添加React.cloneElement绑定时,一切正常(第一个代码示例)

但是

在构造函数中添加绑定顶部时似乎调用某种无限循环。我仍然无法弄清楚为什么? 这两者有什么区别?

enter image description here

1 个答案:

答案 0 :(得分:1)

两种情况下的差异是传递给onClick

的参数

在第一种情况下

onClick: this.selectItem.bind(this,child.props.value)

您正在将函数传递给onClick处理程序

在第二种情况下

onClick: this.selectItem(child.props.value)

发生的事情是你正在调用一个函数,但是onClick接收到一个从函数返回的参数,基本上是null因此会产生问题。组件进入无限循环的原因是你遇到onClick: this.selectItem(child.props.value),正如我所说this.selectItem(child.props.value)向onClick处理程序返回一个值,而它期望一个函数,因此每次你{{1}调用函数将为返回值调用,因为你在同一个函数中使用render,它会在状态发生变异后触发重新渲染,从而进入无限循环