不可变状态是ReactJs中的一个功能特性
Immutable state is a functional feature in ReactJs?
命令式程序最重要的特性是状态及其修改。
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 });
- 按下一个HTML按钮,该按钮使用一个功能在同一个新窗口中打开URL
- 使用单选按钮参考另一个功能
- 流星:移除不是一个功能
- 浏览器同步摄像头加速视频播放不是一个功能
- 谷歌应用程序脚本搜索UI下一个和上一个功能
- 如何使用上一个/下一个功能循环数组中的图像
- 是否可以设置一个功能“;联系我们”;页面使用HTML/CSS
- 只有在前一个功能成功完成的情况下,我才能正确地启动此功能
- 如果另一个功能完成,则执行该功能,而不是何时
- 单击和键控操作可以完成一个功能
- 如果选中单选按钮,如何转到另一个功能?(Javascript)
- 你能在javascript中命名一个功能点击吗?
- 使用 firebase 获取$add angular 应用程序不是一个功能
- 在按钮单击中将一个功能更改为第二个功能
- 在谷歌地图自动补充之后启动一个功能
- 单击圆圈时启动一个功能 - 传单
- 这是一个功能声明、表达式和对象吗?
- 谷歌图表:嗨不是一个功能
- 灯箱“下一个”功能仍然显示已隐藏的元素 (li) 显示:无;
- 有一个功能可以将字符串很好地缩短为一个、两个或三个字母