命令式计划最重要的特征是国家及其修改。
ReactJs鼓励尽可能多的函数式编程(例如使用纯度,高阶函数)。我想知道在ReactJs中使用immutable state这个特征仍然是一个必要的特征还是可以被视为功能性的“国家风格”?
理论上,纯粹命令式程序中React状态和状态之间有什么区别?
答案 0 :(得分:2)
理论上,纯粹命令式程序中React状态和状态之间有什么区别?
在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 });