首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在function /Redux/Redux Toolkit应用程序中键入thunk创建者函数

在function /Redux/Redux Toolkit应用程序中键入thunk创建者函数
EN

Stack Overflow用户
提问于 2022-11-05 02:36:33
回答 1查看 46关注 0票数 1

我有两个非常相似的特性(AI的“修补”和HTML画布上的“输出”)。他们每个人在应用程序中都有一个标签。修补工作良好,并正在由用户基础使用,而输出是当前的WIP。

这些特性具有几乎相同(但并非微不足道)的组件和状态,当然,我希望尽可能多地共享它们。

我有这方面的工作,但我对打字感到困惑,我也不确定这是否是解决这个问题的好办法。

这是设置:

为了共享还原器逻辑和初始状态,我将createSlice包装为createGenericCanvasSlice,根据RTK指南:https://redux-toolkit.js.org/usage/usage-with-typescript#wrapping-createslice

代码语言:javascript
复制
export const createGenericCanvasSlice = <
  Reducers extends SliceCaseReducers<GenericCanvasState>
>({
  name = '',
  initialState,
  reducers,
}: {
  name: string;
  initialState: GenericCanvasState;
  reducers: ValidateSliceCaseReducers<GenericCanvasState, Reducers>;
}) => {
  return createSlice({
    name,
    initialState,
    reducers: {
      ...genericCanvasReducers, // <--- the generic reducers below
      ...reducers,
    },
  });
};

一般的还原器对象如下所示:

代码语言:javascript
复制
export const genericCanvasReducers = {
  setTool: (
    state: GenericCanvasState,
    action: PayloadAction<InpaintingTool>
  ) => {
    state.tool = action.payload;
  },
  toggleTool: (state: GenericCanvasState) => {
    state.tool = state.tool === 'brush' ? 'eraser' : 'brush';
  },
  setBrushSize: (state: GenericCanvasState, action: PayloadAction<number>) => {
    state.brushSize = action.payload;
  },
  // etc
};

然后,每个功能都会得到自己的部分,如下所示:

代码语言:javascript
复制
const inpaintingSlice = createGenericCanvasSlice({
  name: 'inpainting',
  initialState: initialInpaintingState as GenericCanvasState,
  reducers: {
    // addition reducers here if needed
  },
});

const outpaintingSlice = createGenericCanvasSlice({
  name: 'outpainting',
  initialState: initialOutpaintingState as GenericCanvasState,
  reducers: {
    // addition reducers here if needed
  },
});

这很好;我可以为createGenericCanvasSlice创建的片分派操作,但是我必须提前知道是想要修复操作还是想要输出操作。

为了解决这个问题,我为每个泛型操作生成了块,它们接受第二个参数(当前选项卡名)。在thunk内部,检查选项卡名,并将适当的操作分派给适当的切片。

代码语言:javascript
复制
/**
 * Given the two possible actions, returns a thunk that accepts a payload and tab name
 * and dispatches the appropriate action to the appropriate slice.
 */
const createCanvasThunk =
  (inpaintingAction, outpaintingAction) =>
  (payload, activeTabName) =>
  (dispatch, getState) => {
    if (activeTabName === 'inpainting') {
      dispatch(inpaintingAction(payload));
    } else if (activeTabName === 'outpainting') {
      dispatch(outpaintingAction(payload));
    }
  };

/**
 * Creates an object with all the thunks, where the key is the action name. 
 */
export const canvasThunks = _.reduce(
  genericCanvasReducers,
  (thunks, _action, key) => {
    thunks[key] = createCanvasThunk(
      inpaintingActions[key],
      outpaintingActions[key]
    );
    return thunks;
  },
  {}
);

这是可行的,但我无法计算出我的生命,createCanvasThunkreduce回调的类型。

EN

回答 1

Stack Overflow用户

发布于 2022-11-05 09:29:02

最后,我使用了一个简单得多的解决方案。我创建了一个名为canvas的新的状态片段,并给它属性inpaintingoutpainting,每个属性都有泛型画布状态的副本。

我给了canvas片另一个属性currentCanvas,即"inpainting" | "outpainting"

代码语言:javascript
复制
export interface CanvasState {
  currentCanvas: ValidCanvasName;
  inpainting: GenericCanvasState;
  outpainting: GenericCanvasState;
}

我向每个还原器添加了逻辑,以使用currentCanvas作为基本canvas片的索引,然后执行相同的逻辑。

代码语言:javascript
复制
    setTool: (state, action: PayloadAction<InpaintingTool>) => {
      state[state.currentCanvas].tool = action.payload;
    },

最后一步是更新我所有的选择器。我从新的canvasSlice导出了一个方便的选择器,以获得当前的活动画布:

代码语言:javascript
复制
export const currentCanvasSelector = (state: RootState) =>
  state.canvas[state.canvas.currentCanvas];

我的选择器现在看起来如下:

代码语言:javascript
复制
const inpaintingBrushSelector = createSelector(
  [currentCanvasSelector, activeTabNameSelector, areHotkeysEnabledSelector],
  (currentCanvas: GenericCanvasState, activeTabName, areHotkeysEnabled) => {
    const { tool, brushSize, shouldShowMask } = currentCanvas;

    return {
      tool,
      brushSize,
      shouldShowMask,
      activeTabName,
      areHotkeysEnabled,
    };
  },
  {
    memoizeOptions: {
      resultEqualityCheck: _.isEqual,
    },
  }
);

我们可能希望将一些状态(例如画布画笔半径)从inpainting/outpainting级别提升到基本的canvas级别。然后,我们只需从适当的还原器中删除附加的currentCanvas索引。

我们可能希望在组件内部进行特殊处理,这取决于我们是在修复还是在外涂。这将通过组件中的一个简单的条件检查来处理。

因此,最终的结果是非常简单的,我们现在只需要有特殊处理的领域,其中的特点分歧。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74324684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档