繁体   English   中英

如何在 Reducer React Typescript 中设置条件负载

[英]How to Set Conditional Payload in Reducer React Typescript

我在我的应用程序中使用useReducer()useContext()钩子创建了应用程序上下文,控制我的应用程序中的favourites状态(收藏夹图像)。 带有收藏夹的屏幕仅显示用户之前从另一个屏幕保存的项目列表(因此我使用Context )。

我的管理方式是,在ScreenA我为每个图像都有一个按钮,可以将其添加到收藏夹。 ScreenB监视上下文( favourites )中的更改并显示其内容。

我的减速器基本上有 2(两个)函数: ADD_FAVOURITEDELETE_FAVOURITE 但是,我还想实现REPLACE_FAVOURITE ,它将在用户刷新屏幕( RefreshControl )时运行。 但是,我无法添加此类操作,因为有效负载的类型不能是数组。

这是我的减速器的一个例子:

export type FavouritesItem = {
    created_at?: string;
    id: number;
    image: ImageType;
    image_id?: string;
    sub_id?: any;
    user_id?: string;
};

export const favouritesReducer = (
    state: FavouritesItem[],
    action: { type: string; payload: FavouritesItem }
) => {
    switch (action.type) {
        case ContextTypes.Delete:
            return [
                ...state.filter((product) => product.id !== action.payload.id),
            ];
        case ContextTypes.Add:
            return [
                ...state,
                {
                    created_at: action.payload.created_at,
                    id: action.payload.id,
                    image: action.payload.image,
                    image_id: action.payload.image_id,
                    sub_id: action.payload.sub_id,
                    user_id: action.payload.user_id,
                },
            ];
        case ContextTypes.Replace: //return action.payload or smth
        default:
            return state;
    }
};

我想我可以使用这样的条件负载:

action: { type: string; payload: FavouritesItem | FavouritesItem[] }

但这将是错误的,因为有效载荷的属性不是数组有效载荷的一部分。

在这种情况下我能做什么? 如何避免在此处设置新的减速器并添加替换操作?

如果你想为不同的动作有不同的有效载荷,那么定义一个这样的动作类型

enum ContextTypes {
  Add,
  Delete,
  Replace
}

type Action = 
    | { type: ContextTypes.Add, payload: FavouritesItem }
    | { type: ContextTypes.Delete, payload: FavouritesItem }
    | { type: ContextTypes.Replace, payload: FavouritesItem[] }

这可以表明,我们对不同的动作使用不同的有效载荷。

然后,对于减速器,使用我们定义的 Action 的动作类型

export const favouritesReducer = (
    state: FavouritesItem[],
    action: Action
) => {
    switch (action.type) {
        case ContextTypes.Delete:
            return [
                ...state.filter((product) => product.id !== action.payload.id),
            ];
        case ContextTypes.Add:
            return [
                ...state,
                {
                    created_at: action.payload.created_at,
                    id: action.payload.id,
                    image: action.payload.image,
                    image_id: action.payload.image_id,
                    sub_id: action.payload.sub_id,
                    user_id: action.payload.user_id,
                },
            ];
        case ContextTypes.Replace: 
            // Something like this depending on your need
            return [...state, ...action.payload]
        default:
            return state;
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM