我应该在哪里放置旨在将用于 ngrx 存储的数据转换为效果或缩减器的业务逻辑?

Where should I put business logic intended to transform data meant for the ngrx store: into effects or reducers?

我的问题与 ngrx effectsreducers.

有关

我需要先转换从后端检索到的数据,然后再将其放入 ngrx 存储区。从后端检索的数据是 Message 的普通数组(Message 是我应用程序中的自定义类型):

Message[]

我需要将数组转换为以下内容:

Map<string, Message[]>

基本上我是按交易对手(收件人或发件人)ID(密钥)对用户的消息进行分组。

我不确定在哪里执行从 Message[]Map<string, Message[]> 的转换:我应该将转换业务逻辑放入 @Effect 还是放入reducer 函数?

转换可以进入 effect 或 reducer。

如果需要执行任何验证,我会把它放在效果中 - 我可以选择发送错误操作。

否则,我会将其放入 reducer,因为我通常会在此处将操作有效负载转换为状态。

还有另一种选择:您可以使用选择器。也就是说,消息可以作为一个简单的数组存储在状态中,并且可以使用选择器来转换状态的消息,按交易对手或其他任何方式对它们进行分组。如果我有多种消息分组方式,这就是我会选择的选项。

@ngrx/example-app 包含一些示例 selectors:

/**
 * A selector function is a map function factory. We pass it parameters and it
 * returns a function that maps from the larger state tree into a smaller
 * piece of state. This selector simply selects the `books` state.
 *
 * Selectors are used with the `select` operator.
 *
 * ```ts
 * class MyComponent {
 *  constructor(state$: Observable<State>) {
 *    this.booksState$ = state$.select(getBooksState);
 *  }
 * }
 * ```
 */
export const getBooksState = (state: State) => state.books

我的做法是像过去一样在服务中获取和转换数据。

Effects 对动作做出反应并通过服务进行调用以取回数据并根据收到的响应分派其他动作。

这使得测试更容易,因为服务与效果分开,主要目的是对特定操作做出反应,而不是打包数据。

Reducer 可用于此目的,但出于可读性目的,您仍应保持其整洁

我的意见:

  1. 从后端检索的数据将在存储中保持不变。

  2. 使用选择器作为哑组件的业务逻辑(组合、转换等)。

  3. 也许唯一的改造就是使用normalizr来扁平化数据。