如何使用 Redux ToolKit 扩展 reducer 中的 case?

How can I extend cases in reducers with Redux ToolKit?

我正在制作一个插件,其中有一些可以在减速器中处理的通用操作。我不确定如何做到这一点,以便有人可以使用相同的操作扩展其他案例。我有一些这样的代码:

export default function createStore() {
  return configureStore({
    preloadedState: initialStoreState,
    reducer: {
      workingStores: workingStoreReducer,
    },
  });
}

reducer 就是你所期望的:

export default createReducer(initialWorkingStoreState, (builder) => {
  builder
    // chained for a number of actions rather than just one in reality
    .addCase(anImportedAction, (state, { payload }) => {}); 

基本上使用我的插件的人可能有额外的操作来修改 workingStores 的状态。

我正在考虑以一种看似复杂的方式解决问题,其中 createStore 可以进行回调,然后我的 workingStoreReducer 成为 getWorkingStoreReducer 的方法,该方法将进行回调...

export default function getWorkingStoreReducer(extensions) {
  return createReducer(initialWorkingStoreState, (builder) => {
    exensions(builder); // method would add cases to builder
    builder.addCase(anImportedAction, (state, { payload }) => {}); 

  });
}

这看起来很复杂,所以希望我在文档中遗漏了一个更简单的东西

提前编写构建器回调是一种选择吗?

// Your code
export const createBuilder = (additionalCases = []) => builder => {
    builder.addCase(anImportedAction, (state, { payload }) => {})
        .addCase(anImportedAction, (state, { payload }) => {})

    additionalCases.forEach(([action, reducer]) => builder.addCase(action, reducer)
}

const workingStoreReducer = createReducer(initialWorkingState, createBuilder());

在其他地方,扩展案例并重建减速器

const builderCallback = createBuilder([
  [anExtendedAction, (state, { payload }) => {}],
  [anExtendedAction, (state, { payload }) => {}],
]);
const workingStoreReducer = createReducer(workingState, builderCallback);

// Replace store reducer

我最终使用了我在 OG 问题中提出的扩展方法。我找不到明显不同的答案。

我的减速器:

export default function getReducer(extension?: Function) {
  return createReducer<number | null>(null, (builder) => {
    if (typeof extension === 'function') {
      extension(builder);
    }

    builder
      .addCase(eventNewDocAction, (_, { payload }) => {
        const { workingDocumentId } = payload;

        return workingDocumentId;
      })
      .addCase(
        eventCloseDocAction,
        (_, { payload }) => payload.workingDocumentId,
      );
  });
}

我的方法作为 extension 传递给上面


export default function (builder) {
  builder.addCase(eventGenericAction, (state, { payload }) => {
    const { documentData, evt } = payload;
    const { workingDocumentId } = documentData;
    const evtName = evt.name as EventType;

    if (activeDocumentEvents.has(evtName)) {
      return workingDocumentId;
    }

    // noop
    return state;
  });
}

然后我的 reducer 键在 configureStore 我有这个:

// extension.workingDocumentId is the above method that adds eventGenericAction
workingDocumentId: getWorkingDocumentIdReducer(
        extensions.workingDocumentId ?? undefined,
      ),