NgRx - 状态如何组合和初始化

NgRx - How are states combined and initialized

当我们初始化商店时:

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

我们确实将 reducer 传递给 Store 进行存储。但是我们实际上从未将初始状态传递给商店,除了在 r​​educers 函数中定义它:

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

SO,是不是在application bootstraps的时候,调用了一次所有的reducer,从reducer定义中获取初始状态,然后将状态存储到NgRx Store中? 如果是这样,是不是每个reducer都必须有一个初始状态值?否则状态将始终未定义?

并且,如果在 bootstrap 处调用所有 reducer,NgRx 如何确保 reduce 必须到达默认情况?:

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

非常感谢! 感谢任何帮助!!

每次将一个动作发送到商店时,每个 注册的减速器都会被调用。 reducer 只是一个函数,它采用当前状态加上一个动作,return 是一个新状态。

所以是的,在 bootstrap 上调度了一个 init-action(因此调用了每个 reducer)。如果你使用 store-devtools for example, you will see that the initial action is called @ngrx/store/init。 由于此时当前状态未定义,reducer 函数调用如下:someReducer(undefined, { type: '@ngrx/store/init' })

当一个函数被调用时参数为 undefined 并且它有一个具有默认值的参数,它将使用该默认值。

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'

这对您来说可能并不新鲜。但希望它有助于回答您关于初始状态的问题:

正如我所说,在调用 init-action 之前,当前状态是 undefined。因此,当 reducer-function 的参数具有默认值(初始状态)时,存储将使用该初始状态进行初始化。 如果您没有为 reducer 定义默认值,则该状态切片将保持 undefined。 这可能是一个有效的场景。例如,考虑一个处理管理部分操作的减速器。除非具有提升权限的用户使用您的应用程序,否则您可能不想在该状态片中拥有任何内容。

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

你不想在默认情况下 return initialState 因为每个 reducer 都会在每个 action-dispatch 上被调用,默认案例应该 return state。 store 不知道 action 的用途是什么 reducer。它使用当前状态和分派的操作调用每个 reducer,并期望返回一个(新的)状态。
某个减速器是否应对某个动作做出反应取决于您。每个其他不应该对此操作做出反应的减速器应该 return 它是未改变的状态( 通过 default 情况 )。当然,您可以让多个 reducer 对同一个动作做出反应!

在您的情况下,如果在默认情况下每个减速器 returns initialState 您的整个应用程序状态将重置为其初始状态,除了对调度操作做出反应的减速器。

TL;DR 你的问题:

  • 是的,所有 reducer 函数都在 bootstrap(以及所有其他动作调度)上被调用...
  • ... 是的,那是商店用初始状态初始化的时候。
  • 不,减速器不能总是有初始状态*
  • 如果状态片最初是 undefined,它仍然可以通过减速器通过 return 新状态对动作做出反应来改变。
  • 每个不对动作做出反应的减速器都应该 return 通过 default-case 的当前状态。

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