Electron-Redux、Typescript、Redux-Observable 和类型化操作

Electron-Redux, Typescript, Redux-Observable and Typed Actions

我来自 ngrx 背景并且非常习惯使用类型化操作的 ngrx 方式。

export class RestoreWindowState implements FluxStandardAction {
  public readonly type = windowActionTypes.WINDOW_RESTORE_STATE;

  constructor(public payload: IWindowState) {}
}

FluxStandardAction 看起来像这样

export interface FluxStandardAction {
  type: string;
  payload?: any;
  error?: boolean;
  meta?: any;
}

我编写了一个自定义中间件来将 new windowActions.RestoreWindowState(state) 转换为普通对象。这是我的中间件的样子。

export const actionToPlainObjectMiddleware = store => next => action => {
  if (typeof action === 'object' && action.type) {
    const toForward = { ...action };
    return next(toForward);
  } else {
    throw new Error('Action must be FSA');
  }
};

现在如果我这样做

const loadWindowStateFromStorageEpic = action$ =>
  action$.ofType(windowActionTypes.WINDOW_LOAD_STATE_FROM_STORAGE).pipe(
    mapTo(() => {
      const windowState = WindowStateKeeper.load('main');
      return new windowActions.RestoreWindowState(windowState);
    }),
  );

我得到

Error: Action must be FSA

我哪里错了?

问题是您使用的是 mapTo 而不是 mapmapTo 采用单个参数,即您要映射到的原样值。而 map 采用一个投影函数,该函数被调用并用于将当前值映射到某个其他值——这就是您想要的。

// v--------- here
mapTo(() => {
  const windowState = WindowStateKeeper.load('main');
  return new windowActions.RestoreWindowState(windowState);
})

// change to
map(() => {
  const windowState = WindowStateKeeper.load('main');
  return new windowActions.RestoreWindowState(windowState);
})

所以在这种情况下,您将操作映射到函数,而该函数就是按原样分派的。