React基础组件的事件绑定

在React中, 对于组件事件的绑定是有很大的坑的.
比如经常会报如下这种错误: Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
这种错误引起的原因是在事件绑定的位置直接使用了方法, 而不是调用的匿名函数.

比如如下这样就会报错:

 

解决方法:

 

注意, 在onclick的地方, 我们把直接放上去的函数onClick={editStop(form)}改为了使用匿名函数来调用onClick={()=>{editStop(form)}
也就是说使用一个函数将我们的onclick函数句柄包裹起来.

还可以看一下下面的例子:

class ErrorSimulation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      x : 1
    };
  }
  sayHello(){
    console.log("sayHello");
  }
  _changeValue(newValue){
    console.log("_changeValue invoke!");
    //你会发现虽然我们没有点击下面的超链接,但是这里会无限打印log,所以说react会自动执行下面的onClick表达式,从而得到真正的onclick函数句柄,
 //进而导致无限修改state与reRender,直到内存溢出。因此可以是onClick={this._changeValue.bind(2)}或者onClick={()=>{this._changeValue(2)}},
 //后者当react执行onClick表达式的时候得到的是一个函数
    this.setState({newValue});
  }
  render() {
    return (
    
    )
  }
}
ReactDOM.render(
  ,
  document.getElementById('container')
);

参考资料:最重要的一篇 Why does this error exist: “Invariant Violation: Cannot update during an existing state transition” setState(...): Cannot update during an existing state transition
总结: 你可以看到,我们的第二个a标签我们onClick是直接调用了函数,所以会导致无限渲染元素,导致内存溢出。而第一个a标签,我们使用了bind,所以必须点击才能触发,这才是我们想要的结果。

你可能感兴趣的:(React基础组件的事件绑定)