NgRx-如何合并和初始化状态 [英] NgRx - How are states combined and initialized

查看:122
本文介绍了NgRx-如何合并和初始化状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

初始化商店时:

StoreModule.provideStore({r1: Reducer1, r2: Reducer2, ...})

我们确实将减速器传递到要存储的商店.但是,除了在reducers函数中定义初始状态外,我们从未真正将初始状态传递给商店:

we do pass the reducers to the Store to be stored. But we never actually pass the initial states to the store, except defining it in the reducers functions:

const someReducer = (state = initialState, act: Action) => { ... }

那么,是否是当应用程序引导时,所有的reducer都被调用一次以从reducer定义中获取初始状态,然后将该状态存储在NgRx Store中? 如果是这样,是否每个减速器都必须具有初始状态值?否则状态永远是不确定的?

SO, is it that when application bootstraps, all the reducers are called once to acquire the initial state from reducer definition, and then store the state in the NgRx Store? If so, is it that every reducer must have an initial state value? otherwise the states will always be undefined?

并且,如果在引导程序中调用了所有的reducer,NgRx如何确保reduce必须达到默认情况?:

And, if all reducers are called at bootstrap, how does NgRx make sure that the reduce must get to the default case?:

case ...:
   ...
default:
   return initialState

非常感谢! 任何帮助表示赞赏!

Thanks a lot! Any help appreciated!!

推荐答案

每次将动作调度到商店时,都会调用每个注册的reducer.约简器只是一个需要当前状态加上一个动作并返回新状态的函数.

Every time an action is dispatched to the store, every registered reducer is called. A reducer is just a function that takes the current state plus an action and returns a new state.

是的,在引导程序上调度了一个init-action(因此调用了每个reducer).例如,如果您使用 store-devtools ,您会看到初始操作称为 @ngrx/store/init . 由于此时未定义当前状态,因此使用以下命令调用reducer函数:someReducer(undefined, { type: '@ngrx/store/init' })

So yes, on bootstrap an init-action is dispatched (and therefore every reducer is called). If you use store-devtools for example, you will see that the initial action is called @ngrx/store/init. Since the current state is undefined at this point, the reducer-function is called with the following: someReducer(undefined, { type: '@ngrx/store/init' })

当函数使用参数undefined调用并且具有默认值的参数时,它将使用该默认值.

When a function gets called with a parameter that is undefined and it has a parameter with a default value, it will use that default value instead.

function funcWithoutDefault(myParam) {
    console.log(myParam);
}

funcWithoutDefault('hello'); // 'hello'
funcWithoutDefault(undefined); // undefined

function funcWithDefault(myParam = 'world') {
    console.log(myParam);
}

funcWithDefault('hello'); // 'hello'
funcWithDefault(undefined); // 'world'

这对您来说可能不是什么新鲜事.但希望能帮助您回答有关初始状态的问题:

That's probably nothing new to you. But hopefully it helps to answer your question about initial state:

正如我所说,在调用init-action之前,当前状态为undefined.因此,当化简函数具有默认值(初始状态)的参数时,将使用该初始状态初始化存储. 如果您没有为reducer定义默认值,则该状态片保持为undefined. 这可能是有效的方案.例如考虑处理一个管理部分的动作的reducer.除非具有较高权限的用户使用您的应用程序,否则您可能不希望该状态切片中包含任何内容.

As I said, the current state is undefined before the init-action is called. So when the reducer-function has a parameter with a default value (the initialstate), the store will be initialized with this initial state. If you don't define a default value for a reducer, that slice of the state stays undefined. This could be a valid scenario. Consider for example a reducer that handles actions for an admin-section. Unless a user with elevated rights uses your application, you might not want to have anything in that state-slice.

现在我认为您的问题来自:

Now to the point where I presume your question came from:

您不想在默认情况下返回initialState!由于每个reducer都会在每次动作分派上调用,因此默认情况下应该为return state. 商店不知道动作意味着什么.它使用当前状态和已调度的操作调用每个化简器,并期望恢复到(新)状态.
某个减速器是否应该对某个动作做出反应取决于您.所有其他不应该对此动作做出反应的减速器都应返回其不​​变状态(通过 default case ).当然,您可以让多个异化剂对同一动作做出反应!

You don't want to return the initialState in the default case! Since every reducer gets called on every action-dispatch, the default case should return state. The store doesn't know what reducer an action is meant for. It calls every reducer with the current state and the dispatched action and expects to get a (new) state back.
If a certain reducer should react to an action is up to you. Every other reducer that should not react to this action should return it's unaltered state (via the default case). And of course you can have multiple reducers react to the same action!

在您的情况下,如果每个reducer在默认情况下都返回initialState,则除了对调​​度的动作做出反应的reducer之外,您的整个应用程序状态都将重置为初始状态.

In your case, if every reducer returns initialState in the default case your whole app-state would reset to it's inital state, except for the reducer that reacts to the dispatched action.

TL; DR,您的问题:

TL;DR for your questions:

  • 是的,所有reducer-functions都会在bootstrap(以及其他所有动作分派)上被调用...
  • ...是的,这就是商店以初始状态初始化的时候.
  • 否,异径管不一定总是具有初始状态*
  • 如果状态片最初是undefined,则化简器仍可以通过返回新状态来对动作做出反应来对其进行更改.
  • 每个减速器不对动作做出反应,应该通过default -case返回当前状态.
  • Yes, all reducer-functions get called on bootstrap (and on every other action dispatch)...
  • ... and yes, that is when the store gets initialized with the initial state.
  • No, a reducer must not always have an initial state*
  • If a slice of state is initially undefined, it can still be changed by the reducer reacting to an action by returning a new state.
  • Every reducer not reacting to an action should return the current state via the default-case.

*当然,这仅在应用程序的其余部分能够处理未定义状态时才有意义

这篇关于NgRx-如何合并和初始化状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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