为什么我需要在地图范围内绑定此箭头功能?

时间:2017-12-20 09:28:27

标签: javascript reactjs ecmascript-6 arrow-functions

我正在尝试使用li上的onClick事件从数组对象中显示数组,我正在使用箭头函数,但我发现我需要绑定地图范围内的函数,为什么会这样?是不是箭头功能的目的是消除绑定的需要?

 class ListRecipes extends React.Component   {

    showIngredients = (item) => {
        console.log(item.ingredients)
    }

    render() {
    const { list } = this.props;
    let Recipe = list.map((item, index) => {
        let boundClick = this.showIngredients.bind(this, item);
        return <li key={index} onClick={boundClick}> {item.recipeName} </li>
    })
    return (
        <div>
            <ul>
                {Recipe}
            </ul>
        </div>
        )
    }
}

此代码从上面返回一个新函数有什么区别?

class ListRecipes extends React.Component   {

    showIngredients = (item) => (event) => {
        console.log(item.ingredients)
    }

    render() {
    const { list } = this.props;
    let Recipe = list.map((item, index) => {
        return <li key={index} onClick={this.showIngredients(item)}> {item.recipeName} </li>
    })
    return (
        <div>
            <ul>
                {Recipe}
            </ul>
        </div>
        )
    }
}

3 个答案:

答案 0 :(得分:0)

当您编写onClick={this.showIngredients(item)}时,您没有为onClick分配函数引用但是调用它

您可以将其更改为

let Recipe = list.map((item, index) => {
    return <li key={index} onClick={() => this.showIngredients(item)}> {item.recipeName} </li>
})

同样使用let boundClick = this.showIngredients.bind(this, item);,您将showIngredients函数绑定到上下文并向其传递一个额外的参数,因为bind返回一个新函数,所以boundClick是一个函数,然后后来被分配到onClick

答案 1 :(得分:0)

我认为这段代码通常是首选:

let boundClick = this.showIngredients.bind(this, item);

您正在绑定要传递给showIngredients函数的项目。因此,您最终会创建items.length数量的单独函数引用,每个函数引用都绑定到此项和当前项。

答案 2 :(得分:0)

在进行任何其他操作之前,我们需要了解onClick的回调侦听器中传递的参数为event。 那个

function myMethod(event) {
  // only event is passed as argument
}
<div onClick={myMehtod}/>

那么问题是,那么如何传递其他参数呢?简单。从侦听器调用所需的方法。

function calculate(item){
  // no event trace here
}

<div onClick={function(event) { calculate(item) }}/>
// OR better, fat arrow
<div onClick={event => calculate(item)}/>

请记住,粗箭头始终绑定到这个作用域,而不是原型。

class Component {
  scopedMethod = () => {
     this.name = 'John';
  }
  prototypeMethod() {
    this.name = 'John';
  }
  render() {
    return (
      <div>
        {/* works */}
        <button onClick={this.scopedMethod}/>
        {/* OOPS, 'this' is event rather then component */}
        <button onClick={this.prototypeMethod}/>
        {/* works */}
        <button onClick={() => this.prototypeMethod()}/>
        {/* works */}
        <button onClick={this.prototypeMethod.bind(this)}/>
      </div>
    )
  }
}

希望这为我们带来了启示。所以问题是何时以及为什么我将使用范围绑定方法而不是原型方法,反之亦然?好吧,原型方法很便宜。始终尝试使用它们。但是,某些开发人员避免使用lambda函数(render内部的生成函数),因为它可能导致性能问题。当您需要在一秒钟内重新渲染组件10x时,新的lambda将被创建10x。