修改组件的状态然后调用 "setState(this.state)" 是一个好习惯吗?

Is it a good practice to modify a component's state and then call "setState(this.state)"?

我正在使用 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)吗?

您可以直接调用 this.forceUpdate().

而不是调用 this.setState(this.state)

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

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

boolean shouldComponentUpdate(object nextProps, object nextState)
默认为

returns true。如果你不想重新渲染 make shouldComponentUpdate(object nextProps, object nextState) to return false.

引自 Facebook 文档:

By default, shouldComponentUpdate always returns true to prevent subtle bugs when state is mutated in place, but if you are careful to always treat state as immutable and to read only from props and state in render() then you can override shouldComponentUpdate with an implementation that compares the old props and state to their replacements.

除了不变性(这总是好的),第二好的是 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})