【问题标题】:What prevents code from changing the store state?是什么阻止代码改变存储状态?
【发布时间】:2017-07-05 16:00:32
【问题描述】:

store 有一个名为 getState 的方法,它将返回商店的当前状态。

是什么阻止了我的应用程序中某处的代码(意外地)从store 修改返回的state

假设我称之为:

let state = store.getState();
state.someProperty = 'fun';

我在store 对象的getState 上找到的实现只是返回被每个新操作覆盖的内部状态对象。

const getState = () => state;

在动作/新状态之间,是什么阻止了代码修改将被另一个订阅者读取的状态?在上面的示例中,将someProperty 设置为'fun' 将在state 属性上的store 内持续存在,直到被覆盖。

虽然我显然不应该修改状态,但一个简单的错误可能会将状态绑定到某个(在不知不觉中)修改其输入的组件 - 可能是在角度环境中的 2 向绑定上?

<app-some-component [user]="state"></app-some-component>

不应该将getState() 实现为其state 模型的克隆吗?

附:这与 Angular 没有特别的关系——这就是我没有添加标签的原因——让更多不习惯 Angular 的人回答这个问题。

【问题讨论】:

    标签: redux getstate


    【解决方案1】:

    答案是:什么都没有 :)

    核心 Redux 库本身在技术上实际上并不关心状态是否发生突变。您实际上可以在 reducer 中进行变异,或者让应用程序的其他部分获取状态树并对其进行变异,而商店本身不会知道或关心。

    但是,突变会破坏时间旅行调试,并使测试变得不可靠。更重要的是,React-Redux 库假设您不可变地处理您的状态,并依赖浅层相等比较来查看状态是否已更改。 (这就是为什么 "Why isn't my component re-rendering?" 出现在 Redux 常见问题解答中的原因。99.9% 的情况是由于意外突变。)

    如果您担心突变,可以使用 Immutable.js 之类的库来代替普通的 JS 对象,或者使用freezing your state in development to catch mutations 的几个工具之一。

    【讨论】:

    • 你是说我要么需要一个不可变的模型(来自 immutable.js 等),要么我需要在测试/开发时冻结我的状态但在生产中不冻结?
    • 正如我所说,Redux 本身并没有强制不变性。即使您仔细编写 reducer 代码,或使用不可变的更新实用程序库,从技术上讲,代码的任何部分可以调用 getState 并改变内容。如果你想保证不会发生这种情况,你需要使用普通 JS 对象以外的东西,或者冻结普通对象的东西,以确保代码不会在任何地方发生变异。也就是说,应用程序的其余部分当然不应该尝试在任何地方改变状态,但它确实有时会意外发生。
    • 只是忍不住想这很糟糕——容易发生事故——猜测自动化测试将比以往任何时候都更重要......
    • 这里还是在重复我自己:从技术上讲,突变在 Redux 中是合法的,只是通常不是你想要的。如果你想阻止它,我已经列出了你可以使用的方法。例如,我的 Redux 插件目录的 DevTools#Linting 部分列出了可用于帮助捕获错误的各种“冻结在开发”工具。
    • 诚实吗?是的,你是:) 是的,意外突变是一个问题。但正如我所列出的,有很多方法可以解决这个问题。单单是基本的 Redux 模式就可以让事情变得更简单,因为你所有的“写”逻辑都被移到了 reducer,所以所有 intentional 的变化都在一个区域内。从那里,只有mapState 函数和可能的动作创建者应该访问状态,这样就真正缩小了可能进行突变的任何可能的地方。没有 100% 的保证,但在这与冻结/不可变库之间,这应该不是一个有意义的问题。
    猜你喜欢
    • 2021-04-06
    • 1970-01-01
    • 2015-03-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多