NGRX中的减少器和不变性 [英] Reducers and immutability in ngrx

查看:71
本文介绍了NGRX中的减少器和不变性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在ngrx中创建reducer函数时,我阅读的所有内容都说我应该返回原始/先前状态的副本.通过使用传播运算符或通过使用库或诸如JSON.parse(JSON.stringify(state))之类的技巧.

When creating a reducer function in ngrx, everywhere I read says that I should return a copy of the original/previous state. Either by using spread operators or by using a library or tricks like JSON.parse(JSON.stringify(state)).

但是我发现那里有一个陷阱,我找不到任何谈论它的人. 在reducer中返回的最后一个状态是将与所有当前订户和将来的订户共享的状态. 这意味着所有使用特定存储的组件都将看到相同的状态对象.

But I found one catch there and I couldn't find anyone talking about it. The last state returned in a reducer is the state that's going to be shared with all current subscribers and with future subscribers too. That means that all components that use a certain store will see the same state object.

这也意味着,如果在一个组件中更改状态中的任何值(不调度动作),则存储实际上将修改该值,但不会通知其他组件. 如果要在任何地方共享当前状态的副本,那有什么意义呢?

That also means that if any value in the state is changed in one component (without dispatching an action), the store will actually have the value modified, but the other components won't be notified. What's the point in returning a copy of the current state if it's going to be shared everywhere?

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

The word immutable is used all the time, but that state is not immutable at all, because the store returns its own inner object, and not a copy of that.

我了解不变部分是否是开发人员必须遵循的概念.但是,然后需要在使用原始对象/值的组件中进行复制.从reducer返回浅拷贝或深拷贝似乎只是在浪费处理能力和内存.

I understand if the immutable part is a concept that needs to be followed by the developer. But then, the copy of the original object/values needs to be done in the component that uses it. Returning a shallow or deep copy from the reducer seems to be just waste of processing power and memory.

推荐答案

我会尽力回答.

伪代码中的reducer看起来像这样:

A reducer in pesudocode looks like this:

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,则您不是突变状态.传播算子使用新参考创建一个新对象,而新参考是发出更改信号所需要的.

In case ACTION_1 you are not mutating state. The spread operator creates a new object with a new reference and the new reference is what is needed to signal a change.

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

In case ACTION_2 you are cloning the state. You mutate the cloned state and return it. Because the cloned state has a new object reference it signals a change has been made and everyone is happy.

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

In the default scenario, any other action (e.g. ACTION_3) is ignored and the original state is returned signifying that state has not changed. The object reference has not changed and thus "no change" is signalled (this is why it is important not to mutate the original state).

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

When an action is fired off, the action is passed to EVERY reducer. And thus, reducers that don't want to modify their associated piece of state can ignore the action by relying on the default case statement.

一个动作可以并且经常会触发多个减速器的状态变化.

A single action can, and often does, trigger state changes in multiple reducers.

如果返回的对象引用已更改,则它将为所讨论的特定状态触发任何相关的RxJS状态订阅.可以使用一些不错的ngrx选择器来最小化触发哪些订阅.

If the returned object reference has changed, it will trigger any related RxJS state subscriptions for the particular piece of state in question. Which subscriptions are triggered can be minimised using some good ngrx selectors.

PS有一个很棒的库,名为ngrx-store-freeze,它将强制执行无突变"原则.如果您改变状态,它将及早引发错误.这有助于避免难以跟踪的错误.使用meta reducer冻结商店冻结.

PS There's a great library called ngrx-store-freeze which will enforce the "no mutation" principle. It will throw an error early if you mutate state. This helps to avoid hard to track down bugs. Hook into store freeze with a meta reducer.

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

PPS The whole purpose of using the object reference to determine change is because it is much faster to check an object reference than it is to check every value on an object to see if it has changed. This is why immutability is so relevant.

这篇关于NGRX中的减少器和不变性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆