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

时间:2016-10-30 00:20:50

标签: javascript reactjs functional-programming imperative-programming

命令式计划最重要的特征是国家及其修改。

ReactJs鼓励尽可能多的函数式编程(例如使用纯度,高阶函数)。我想知道在ReactJs中使用immutable state这个特征仍然是一个必要的特征还是可以被视为功能性的“国家风格”?

理论上,纯粹命令式程序中React状态和状态之间有什么区别?

1 个答案:

答案 0 :(得分:2)

  

理论上,纯粹命令式程序中React状态和状态之间有什么区别?

  • 反应状态描述应如何呈现内容。
  • 命令状态枚举从状态A到状态B所需的步骤(我猜你已经说过,当你说“命令式程序最重要的特征是状态和他们的修饰“)。

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

但是,最终,如果你想在React中从状态A改为状态B,你可以在事件处理程序中这样做,如果你愿意,可以强制执行,但必须完成而不实际改变初始状态。 e.g。

// 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之前仍然更新。 (这与对象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 });