1

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

ReactJs 鼓励尽可能多的函数式编程(例如使用纯度、高阶函数)。我想知道在 ReactJs 中使用不可变状态这个特性是否仍然是一个命令特性,或者可以被认为是功能性的“状态样式”?

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

4

1 回答 1

2

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

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

在 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);

在第一个示例中(OK),当然,您可以看到一定程度的杂质;foo被修改了,但至少原始状态没有。

在第二个示例(BAD)中,我们的杂质水平相同,但更糟;我们直接修改当前状态,这可能会产生不可预测的结果。我看到太多 Stack Overflow 帖子,有人问“为什么我用this.state??? 做 X 时渲染不正确?” 换句话说,这种不变性范式是出于务实的原因而被强制执行的;也就是说,这就是 React 的设计方式,而任何其他方式都会产生未定义的行为(根据具体情况)。

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

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

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

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

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 });
于 2016-10-30T02:03:07.503 回答