如何为自定义类型创建 Reduce

How to create Reduces for a custom Type

我今天早上在一个购物网站上工作,使用 React Typescript 和 Context API,想使用 React Reducers 来操纵我的购物车 使用我为产品类型创建的自定义类型进行状态,包括项目数组和一些函数... 问题是我不知道如何用CartReducer函数中的Action传递参数,想知道你会怎么做

我的购物车上下文

import * as React from 'react';
import { useQuery } from "react-query";





type ICartContext = [IProductItem[] | undefined, React.Dispatch<React.SetStateAction<IProductItem[] | undefined>>];

export const CartContext = React.createContext<ICartContext>([[], () => null]);



type Action = "Add" | "Update" | "Remove"

const CartReducer = (state: IProductItem[], action: Action) => {

    return state
}


const CartProvider: React.FC<{}> = ({children}: { children?: React.ReactNode }) => {

    const [cart, setCart] = React.useReducer(CartReducer, [], undefined)


    return (
        <CartContext.Provider value={[cart, setCart]}>
            {children}
        </CartContext.Provider>
    );

};

export default CartProvider;

我的类型

interface IProductItem{
    id: number
    title: string
    description: string
    category: string
    image: string
    price: number
    quantity: number
}

type ProductType = {
    items: IProductItem[];
    saveItem: (item: IProductItem) => void
    updateItem: (id: number) => void
    removeItem: (id: number) => void
};

使用 discriminated union 作为您的操作类型:

// each specific action includes a `type` property

interface AddAction {
  type: "Add";
  addedProduct: IProductItem;
}
interface UpdateAction {
  type: "Update";
  updatedProduct: IProductItem;
}
interface RemoveAction {
  type: "Remove";
  removedProduct: IProductItem;
}

// Action is a union of all the possible actions
type Action = AddAction | UpdateAction | RemoveAction;

const CartReducer = (state: IProductItem[], action: Action) => {
  // Since `type` is the only property all actions have in common,
  // it's the only property that can be accessed until narrowing
  // it with a condition or a switch statement

  switch (action.type) {
    case "Add":
      // can access action.addedProduct here
      return state;

    case "Update":
      // can access action.updatedProduct here
      return state;

    case "Remove":
      // can access action.removedProduct here
      return state;
  }
};

// elsewhere:
dispatch({ type: "Add", addedProduct: product })