在render方法的eventHandler中调用setState

时间:2018-07-24 11:31:48

标签: javascript reactjs event-handling render setstate

使用React时,我了解它,因此在组件的render方法内调用setState是一种不好的做法;而是保持此方法纯净。但是,如果我需要基于链接到组件的事件来更新状态,该怎么做?

class Toggle extends React.Component {
   constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
       <button onClick={this.handleClick}>
         {this.state.isToggleOn ? 'ON' : 'OFF'}
       </button>
    );
  }
}

上面的代码来自React的官方教程。正如我们所看到的,事件处理程序绑定到onClick属性,并且在该事件处理程序内部,组件的状态已更改,因此潜在地我们将在从render方法调用时更新状态。因此,我对为什么可以这样做却没有在render方法中显式调用setState感到迷惑不解?与React如何包装普通的html事件有关吗?

3 个答案:

答案 0 :(得分:3)

不好的做法是在render方法中显式调用setState,因为render方法应该能够多次运行而没有任何副作用(不会影响render自身以外的任何内容)

在上面的代码块中,setState绑定到一个单击处理程序,这意味着仅在单击按钮时才调用它,而不是在调用render方法时调用它,因此完全可以。 / p>

回顾:

最好有事件处理程序来更新render方法中的状态,只要它们在事件触发时才被调用即可。

拥有setState或直接在setState函数中调用render的函数是不好

示例

doSomthing = () => {
  this.setState({ foo: 'bar' });
}

render() {
  return (
    <button onClick={this.doSomething}>Click Me</button>
  );
}
// this code is GOOD

上面的示例是确定

doSomething = () => {
  this.setState({ foo: 'bar' });
}

render() {
  this.doSomething();
  return (
    <button>Click Me</button>
  );
}
// this code is BAD

上面的示例是不良

答案 1 :(得分:1)

没有调用函数,仅通过了:

<button onClick={this.handleClick}>
         {this.state.isToggleOn ? 'ON' : 'OFF'}
</button>

答案 2 :(得分:1)

render() {
    return (
       <button onClick={this.handleClick}>
         {this.state.isToggleOn ? 'ON' : 'OFF'}
       </button>
       {this.setState(() => ({}))}
    );
  }

当您尝试执行上述操作时。这会导致渲染问题。 考虑一下setState()的目的是什么。显然要更改组件的状态。现在想想当您的状态改变时会发生什么。是的,您的组件再次被渲染。现在考虑一下,如果某个组件正在渲染,并且它再次找到了setState(),那么它将导致渲染失败。

  

关于事件处理程序的问题,现在是使用的一种良好做法   setState()

这是一个简单的概念,我们在事件调用中使用引用,这意味着在呈现组件时,它不会立即触发它,而是会等待有人调用。很明显,当有人要调用该呼叫时,只会更改状态,并且不会对render()造成影响,并且可以正常工作