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

Immutable state is a functional feature in ReactJs?

本文关键字:一个 功能 状态 ReactJs 不可变      更新时间:2023-09-26

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

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

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

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

  • React state 描述应该如何渲染。
  • 命令式状态列举了从状态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);

在第一个例子中,当然,你可以看到某种程度的杂质;foo被修改了,但至少不是原来的状态。

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

另一个可以产生不可预知结果的例子:

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

,在这种情况下,状态仍然在通知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 });