React 实现pure render的时候,bind(this)隐患

#1

pure render 我就不多说了,附上我另一片文章链接 react如何性能达到最大化(前传)
不论你用不用immutable,只要你想达到pure render,下面值得你注意!!!
一天我和往常一样,开开心心得写着react,用着@pureRender,

export default class  extends Component {
...
  render() {
    const {name,age} =this.state;
    return (
      <div>
        <Person name={name} age={age} onClick={this._handleClick.bind(this)}></Person>//bug 所在
      </div>
    )
  }
...
}

发现一个问题,对于Person这个子组件来说,在父组件re-render的时候,即使Person得前后两个props都没改变,它依旧会re-render。。即使用immutable.js也不好使。。。
原来啊,父组件每次render,_handleClick都会执行bind(this) 这样_handleClick的引用每次都会改。。所以Person前后两次props其实是不一样的。。
那怎么办?把bind(this)去掉?不行 还必须得用
真正的答案是 让父组件每次render 不执行bind(this),直接提前在constructor执行好,修改之后

export default class  extends Component {
  constructor(props){
    super(props)
    this._handleClick= this._handleClick.bind(this)//改成这样
  }
  render() {
    const {name,age} =this.state;
    return (
      <div>
        <Person name={name} age={age} onClick={this._handleClick}></Person>
      </div>
    )
  }
...
}

本文sf地址

1 Like
#2

onClick = {this._handleClick.bind(this)}

改为

onClick = { () => this._handleClick }

如何

#3

类似的问题还有style object

#4

应该不行吧。。这样父组建每次 render ,,,() => this._handleClick就会变成新的。。

#5

是的。。。最好 都提前声明好,,防止父组建 render的时候 ,引起每次 引用 都改变

#6
this._handleClick.bind(this)//改成这样

应该是这样

this._handleClick = this._handleClick.bind(this)
1 Like
#7

学习了

#8

之前也纠结过。
不过最好发现根本解决方案就是props从来都不传函数,使用EventEmitter解耦,减少shouldComponentUpdate判断的复杂度。

#9

赞,楼上方式不错

#10

最近刚好总结了一下。

#11

改好了。。多谢了。。

#12

去掉bind,然后函数改为:
export default class extends Component {
_handleClick=()=>{

}
render() {
return(

)
}

1 Like
#13

现在好多都这么写,但是不怎么明白原理。。。

#14

EventEmitter解耦 这个不太懂 哪里有介绍吗?有链接吗?
用上面那个能解决父组件调用子组件参数问题吗?

#15

ES6里面的箭头函数貌似自动绑定了this的

#16

箭头函数不是自动绑定,这个自己动手试验下就知道了。

源代码

function out() {
  const inner = () => {
    this.test = '';
  }
}

编译代码

'use strict';

function out() {
  var _this = this;

  var inner = function inner() {
    _this.test = '';
  };
}