gpt4 book ai didi

angular - ngrx 中的 reducer 和不变性

转载 作者:行者123 更新时间:2023-12-04 20:28:34 25 4
gpt4 key购买 nike

在ngrx中创建reducer函数时,我读到的所有地方都说我应该返回原始/先前状态的副本。通过使用扩展运算符或使用库或技巧如 JSON.parse(JSON.stringify(state)) .

但是我在那里发现了一个问题,我找不到任何人在谈论它。
reducer 中返回的最后一个状态是与所有当前订阅者和 future 订阅者共享的状态。
这意味着使用某个存储的所有组件都将看到相同的状态对象。

这也意味着,如果状态中的任何值在一个组件中发生更改(没有调度操作),商店实际上会修改该值,但不会通知其他组件。
如果要在任何地方共享,那么返回当前状态的副本有什么意义?

不可变这个词一直在使用,但这种状态根本不是不可变的,因为存储返回它自己的内部对象,而不是它的副本。

我了解不可变部分是否是开发人员需要遵循的概念。但是,原始对象/值的副本需要在使用它的组件中完成。从 reducer 返回浅拷贝或深拷贝似乎只是浪费处理能力和内存。

最佳答案

我会尝试回答。

伪代码中的 reducer 如下所示:

myReducer(state, action) {

switch(action) {

case ACTION_1:
return {...state, prop: action.payload}

case ACTION_2:
const newState = _.cloneDeep(state)
newState.prop = action.payload
return newState

default:
return state
}
}

如果 ACTION_1 你没有改变状态。扩展运算符使用新引用创建一个新对象,而新引用是发出更改信号所需要的。

如果 ACTION_2 您正在克隆状态。你改变克隆状态并返回它。因为克隆状态有一个新的对象引用,所以它表明已经进行了更改并且每个人都很高兴。

在默认情况下,忽略任何其他操作(例如 ACTION_3)并返回原始状态,表示状态未更改。对象引用没有改变,因此发出“没有改变”的信号(这就是为什么不改变原始状态很重要的原因)。

当一个 Action 被触发时,该 Action 被传递给每个 reducer 。因此,不想修改其关联状态的 reducer 可以通过依赖默认 case 语句来忽略该操作。

单个操作可以并且经常会触发多个 reducer 中的状态更改。

如果返回的对象引用发生了变化,它将触发任何相关的 RxJS 状态订阅,以获取相关的特定状态。使用一些好的 ngrx 选择器可以最小化触发哪些订阅。

PS 有一个很棒的库,叫做 ngrx-store-freeze,它将强制执行“无突变”原则。如果你改变状态,它会提前抛出错误。这有助于避免难以追踪的错误。使用元 reducer 连接到商店卡住。

PPS 使用对象引用来确定更改的全部目的是因为检查对象引用比检查对象上的每个值以查看它是否已更改要快得多。这就是不变性如此重要的原因。

关于angular - ngrx 中的 reducer 和不变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51714194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com