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,有什么区别呢?哪个更好呢?



  • 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} />
    


  • @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也不会导致子组件属性变化。



  • 请问写法三怎么传参呢?



  • @zztiswb116
    xxA = (param)=>{ do something };
    <XXView xxxx={this.xxA(param)} />



  • @starsion 这种方法报错
    0_1546496366558_38442b78-3353-445f-b932-b32f7ed2c6f8-image.png
    0_1546496380554_7426302e-eeac-4c82-9e0f-2679abbb0c69-image.png [图片]



  • @zztiswb116 https://reactjs.org/docs/faq-functions.html

    const A = 65 // ASCII character code
    
    class Alphabet extends React.Component {
      constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
        this.state = {
          justClicked: null,
          letters: Array.from({length: 26}, (_, i) => String.fromCharCode(A + i))
        };
      }
    
      handleClick(e) {
        this.setState({
          justClicked: e.target.dataset.letter
        });
      }
    
      render() {
        return (
          <div>
            Just clicked: {this.state.justClicked}
            <ul>
              {this.state.letters.map(letter =>
                <li key={letter} data-letter={letter} onClick={this.handleClick}>
                  {letter}
                </li>
              )}
            </ul>
          </div>
        )
      }
    }
    
    


  • @mirghojam 自定义data属性仅限html,并不适用于react-native



  • @晴明 但他的代码不是react吗?



  • @starsion 那样会立即执行,而且函数里面setState的话会进入死循环



  • 第一种:每次render,都会重新bind,性能肯定不行。
    第二种:多写个constructor钩子。
    第三种:牛逼(破音)!
    第四种:你这个写法和第三种有什么区别嘛?如果想传参,直接(args) => { this.xxA(args) } 我认为就ok啦。


Log in to reply