bind和箭头函数,哪个更好呢?



  • 写法1:

    <XXView xxxx={this.xxA.bind(this)} />

    写法2:

    constructor(props) {
        super(props);
        this.xxA= this.xxA.bind(this);
      }
    

    写法3:

    xxA = ()=>{};
    <XXView xxxx={this.xxA} />
    

    写法4:

    <XXView xxxx={()=>this.xxA} />
    

    1和2一样,3和4一样吧。

    那么实际中大家更倾向哪种写法?

    求教用箭头函数和用bind,有什么区别呢?哪个更好呢?


  • administrators

    P.S 写法4写错了 ,少了括号
    应该是

    <XXView xxxx={()=>this.xxA()} />
    

    推荐写法3

    其实最终代码上 2和3是一致的 1和4是一致的

    1和4的问题在于,由于绑定是在render中执行,而render是会执行多次的,每次bind和箭头函数都会产生一个新的函数,因而带来了额外的开销
    2和3避免了每次产生新的函数,效果等同,显然3的写法更简洁,因而推荐3



  • @sunnylqm 谢谢



  • 经过我的测试,我觉得方法4是最好的。

    2和3会触发“Cannot update during an existing state transition”。
    具体原因是xxA中的代码在render时就会跑一遍。

    1和4中,涉及到传值什么的,4很方便。
    1我不知道怎么传。

    推荐使用

    <XXView xxxx={()=>this.xxA} />
    

  • administrators

    @Alois 我再纠正一次,你的写法4是错误的,
    应该是

    <XXView xxxx={()=>this.xxA()} /> //xxA后必须有括号()
    

    2和3会触发“Cannot update during an existing state transition”。
    具体原因是xxA中的代码在render时就会跑一遍。

    这样的错误只可能是你自己写错了。

    比如写成了xxxx={this.xxA()} 带上了括号,因而在render时直接执行了。写法2和写法3在render时都是不带括号的,请注意!写法4必须要括号,而写法2和3必须不要括号!

    如果是需要传参,那么选择写法1或者写法4(但其实不是最好的做法)
    除此以外,写法3最优(无论写法还是性能)



  • @sunnylqm 再次感谢



  • 修改正确以后,方法1和4都有共同的问题:如果父组件重新render后,给到子组件的属性是一个新的函数实例,而并非完全相同的实例,这样即使子组件是pure-rendering component,也不能起到优化作用。2和3都在this上绑定了bind后的实例,所以重新render也不会导致子组件属性变化。


登录后回复