不可变状态是 ReactJs 中的功能特性?

Immutable state is a functional feature in ReactJs?

命令式程序最重要的特征是状态及其修改。

ReactJs 鼓励尽可能多的函数式编程风格(例如使用纯度、高阶函数)。我想知道在 ReactJs 中使用 immutable state 这个特性是否仍然是一个必要的特性或者可以被认为是功能性的 "style of state"?

从理论上讲,React状态和纯命令式程序中的状态有什么区别?

Theoretically, what is the difference between the React state and state in pure imperative programs?

  • 反应状态描述事物应该如何呈现。
  • 命令式状态 枚举 从状态 A 到状态 B 所需的步骤(我猜你已经说过了,当你说“[the] 命令式程序最重要的特性时是状态及其修改").

在 React 中更新状态(使用 this.setState)的全部目的是通知组件状态已更新,需要重新渲染。

但是,最终,如果您想在 React 中从状态 A 更改为状态 B,您可以在事件处理程序中执行此操作,如果您愿意,可以强制执行,但必须执行 实际上没有改变初始状态。例如

// OK

let foo = this.state.foo;
foo = deriveSomeValue(foo);
this.setState({ foo });

// BAD

this.state.foo = deriveSomeValue(foo);
this.setState(this.state);

在第一个示例中(好的),当然,您可以看到一定程度的杂质; foo修改了,但至少不是原来的状态。

在第二个例子(BAD)中,我们有相同水平的杂质,但更糟;我们直接修改当前状态,这可能会产生不可预测的结果。我看到太多 Stack Overflow 帖子有人问 "why isn't things rendering properly when I do X with this.state???"也就是说,这就是 React 设计的工作方式,任何其他方式都会产生未定义的行为(视具体情况而定)。

另一个可能产生不可预测结果的例子:

const foo = this.state.foo;
foo.someProperty = getSomeValue();
this.setState({ foo });

在这种情况下,状态在通知 React 之前仍然会更新。 (这与对象是 explicitly referenced 而不是隐式复制的事实有关。)

当然,您可以在事件处理程序中以命令式的方式在 React 中从状态 A 转到状态 B,但您必须确保初始状态不会被直接修改。如果您确实看到需要进行一些复杂的修改,那么我建议您对对象执行 deep copy,然后以这种方式进行必要的修改。以下完全没问题:

const foo = cloneObject(this.state.foo);
// `cloneObject` is an entirely contrived function. You'll have to pick a
// deep copying library. Google around for "JavaScript deep copying"
foo.someProperty = getSomeValue();
this.setState({ foo });

或者,您可以使用不可变数据结构,这样如果您(可以在语义上称为)直接修改 属性,它会产生一个全新的对象,而不必修改原始对象。一个好的库将是(如你所提到的)ImmutableJS。

let foo = this.state.foo;
foo = foo.set('someProperty', getSomeValue());
this.setState({ foo });