【问题标题】:Is it a good practice to modify a component's state and then call "setState(this.state)"?修改组件的状态然后调用“setState(this.state)”是一种好习惯吗?
【发布时间】:2015-04-02 17:53:18
【问题描述】:

我正在使用 ReactJS。

我有一个有状态的组件(秒表容器)和多个无状态的子组件(秒表)。

在外部组件中,我正在做这样的事情:

// the outer component is a "container" for multiple stopwatches
tick: function() {
  for (var i = 0; i < this.state.stopwatches.length; i++)
    {
      // if a particular stopwatch is "started", I'll increase it's time
      if (this.state.stopwatches[i].status == "started")
        {
          this.state.stopwatches[i].time.seconds++;
          // do some processing
        }
    }
  // this is the suspicious code!
  this.setState(this.state);
}

请注意,我正在更改 this.state 属性,然后在 state 对象本身上调用 setState()。这对我来说似乎很错误。但是,另一方面,为了操纵 state 对象本身,我必须克隆它然后执行 setState(stateClone),但我不确定是否可以在 JS 中有效地克隆对象,如果我真的不应该这样做。

我可以继续做setState(this.state)吗?

【问题讨论】:

  • 如果你在做你正在做的事情没有面临一些副作用,那么应该没问题。
  • 实际上我在问从 ReactJS 的角度来看这是否是一个好习惯。也许有更好的方法。

标签: javascript reactjs


【解决方案1】:

您可以直接调用this.forceUpdate(),而不是调用this.setState(this.state)

请记住,这不是更新组件状态的推荐方式。如果您不确定自己的修改,请查看Immutability Helpers

【讨论】:

    【解决方案2】:

    这里只有我的两分钱:每次调用 setState 时,React 都会重新渲染:

    boolean shouldComponentUpdate(object nextProps, object nextState)
    

    默认返回true。如果您不想重新渲染,请让shouldComponentUpdate(object nextProps, object nextState) 返回false

    引自 Facebook 文档:

    默认情况下,shouldComponentUpdate 总是返回 true 以防止 state 发生突变时的细微错误,但如果你小心的话 始终将 state 视为不可变的,并且仅从 props 读取和 staterender() 然后你可以覆盖shouldComponentUpdate 使用将旧的 propsstate 与 他们的替代品。

    【讨论】:

      【解决方案3】:

      除了不变性(这总是好的)之外,第二好的是this.setState({stopwatches: this.state.stopwatches})

      使用不变性助手,它看起来像这样:

      var stopwatches = this.state.stopwatches.map(function(watch){
        return update(watch, {
          time: {$set: watch.time + 1}
        });
      });
      this.setState({stopwatches: stopwatches})
      

      或者使用 es6 可以节省一些字符。

      var stopwatches = this.state.stopwatches.map(watch => update(watch, {
          time: {$set: watch.time + 1}
      });
      this.setState({stopwatches})
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-04-25
        • 2017-06-05
        • 2016-05-20
        • 1970-01-01
        • 1970-01-01
        • 2023-02-15
        • 1970-01-01
        相关资源
        最近更新 更多