【问题标题】:Immutable state is a functional feature in ReactJs?不可变状态是 ReactJs 中的一个功能特性?
【发布时间】:2016-10-30 00:20:49
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript reactjs functional-programming imperative-programming


    【解决方案1】:

    理论上,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 之前更新。 (这与对象是 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 });
    

    【讨论】:

      猜你喜欢
      • 2018-11-06
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 2020-04-27
      • 2010-12-20
      • 2021-06-11
      • 2021-07-21
      • 1970-01-01
      相关资源
      最近更新 更多