1

我有两个动作:

export const addToCart = (id: string, qty: number) => async (
  dispatch: Dispatch,
  getState: () => RootState
) => {
  const { data }: { data: IProduct } = await axios.get(`/api/products/${id}`);
  dispatch({
    type: CartActionTypes.CARD_ADD_ITEM,
    payload: {
      id: data.id,
      name: data.name,
      image: data.image,
      price: data.price,
      countInStock: data.countInStock,
      qty,
    },
  });

  localStorage.setItem("cartItems", JSON.stringify(getState().cart.cartItems));
};

export const removeItem = (item: CartProduct) => ({
  type: CartActionTypes.CARD_REMOVE_ITEM,
  payload: item,
});

我创建 Action union 类型并将其传递给 reducer,但它给了我“类型别名'Action'循环引用自身”,我不知道这意味着什么。

export type Action =
  | ReturnType<typeof addToCart>
  | ReturnType<typeof removeItem>;
4

1 回答 1

0

当您有两个泛型类型相互引用时,就会出现循环引用的问题:

type Bar<T> = T;
type Foo = Bar<Foo>;

如您所见,这扩展为:type Foo = Bar<Foo> = Foo = Bar<Foo> = ...,即。你得到一个循环引用。

在您的情况下,有问题的功能是第一个动作创建者:

export const addToCart = (id: string, qty: number) => async (
  dispatch: Dispatch,
  getState: () => RootState
) => {

通过传递getState: () => RootState,您引入了一个循环引用,因为RootState它是一个包含export type Action您稍后导出的联合。

要解决此问题,您必须区分动作创建者thunk。只有前者构成RootState(有关差异的更多阅读,我在这里推荐您:https ://daveceddia.com/what-is-a-thunk/ )。

所以,总而言之,| ReturnType<typeof addToCart>Action联合类型中删除,然后提取

dispatch({
  type: CartActionTypes.CARD_ADD_ITEM,
    payload: {
    id: data.id,
    name: data.name,
    image: data.image,
    price: data.price,
    countInStock: data.countInStock,
    qty,
  },
});

对于动作创建者。

于 2021-05-17T08:51:24.460 回答