【问题标题】:Why do i need to bind this arrow function in scope of map?为什么我需要在地图范围内绑定这个箭头函数?
【发布时间】:2017-12-20 09:28:26
【问题描述】:

我正在尝试使用 li 上的 onClick 事件显示来自数组对象的数组,我正在使用箭头函数,但我发现我需要在 map 范围内绑定该函数,这是为什么呢?箭头函数的目的不就是为了消除绑定的需要吗?

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

【问题讨论】:

  • 当你绑定它会发生什么?没有绑定的代码到底长什么样子?
  • 如果我不绑定它或返回一个新的事件函数它控制台。当页面加载但不是 onClick 时记录数组。 ` showIngredients = (item) => { console.log(item.ingredients) }` onClick={this.showIngredients(item)}

标签: javascript reactjs ecmascript-6 arrow-functions


【解决方案1】:

当您编写 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

【讨论】:

  • 我知道这件事,但他们说要避免使用内联函数。
  • @Juan 好吧,那么bind 是。这与箭头函数和this 的值无关,只是您调用该函数时。
  • @Shubham 感谢您的回答,我也想知道返回新事件和邮政编码中的绑定有什么区别。
  • 查看这个答案stackoverflow.com/questions/45053622/…,了解如何避免在渲染中绑定
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    首先我们需要了解 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)}/>
    

    请记住,胖箭头始终绑定到 this 范围,而不是原型。

    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 函数(在渲染中生成函数),因为它可能会导致性能问题。当您需要将组件重新渲染 10 倍时,新的 lambda 会创建 10 倍。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 2019-05-18
      • 1970-01-01
      • 2021-12-07
      • 1970-01-01
      相关资源
      最近更新 更多