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

Mar*_* Ou 2 ngrx angular ngrx-store

当我们初始化我们的商店时:

StoreModule.provideStore({r1: Reducer1, r2: Reducer2, ...})
Run Code Online (Sandbox Code Playgroud)

我们确实将Reducer传递给Store进行存储.但我们实际上从未将初始状态传递给商店,除了在reducers函数中定义它:

const someReducer = (state = initialState, act: Action) => { ... }
Run Code Online (Sandbox Code Playgroud)

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

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

case ...:
   ...
default:
   return initialState
Run Code Online (Sandbox Code Playgroud)

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

mtx*_*mtx 6

每次将一个动作发送到商店时,都会调用每个注册的减速器.reducer只是一个函数,它接受当前状态和一个动作并返回一个新状态.

所以是的,在bootstrap上调度init-action(因此调用每个reducer).例如,如果您使用store-devtools,您将看到调用初始操作@ngrx/store/init.由于此时当前状态未定义,因此使用以下方法调用reducer-function: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'
Run Code Online (Sandbox Code Playgroud)

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

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

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

你不想initialState在默认情况下返回!由于每个动作调度都会调用每个reducer,因此默认情况应该如此return state.商店不知道动作的减速器是什么意思.它使用当前状态和调度操作调用每个reducer,并期望获得(新)状态.
如果某个减速器应该对某个动作做出反应取决于你.每一个不应对此动作作出反应的减速器应该返回它未改变的状态(通过 default 情况).当然,您可以让多个减速器对同一动作做出反应!

在您的情况下,如果每个reducer initialState在默认情况下返回,则整个app-state将重置为初始状态,除了对调度操作做出反应的reducer.

TL; DR为您提问:

  • 是的,所有reducer-functions都会在bootstrap(以及其他每个动作调度)上调用...
  • ......是的,那就是当商店以初始状态初始化时.
  • 不,减速机不能总是具有初始状态*
  • 如果最初是状态切片undefined,则还原器仍然可以通过返回新状态来响应动作.
  • 每个对动作没有反应的减速器都应该通过default-case 返回当前状态.

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