redux 如何在没有prepare函数的createSlice中使用reducer?

r3i60tvu  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(107)

你好,当我在createSlice中创建reducer时遇到了问题,因为typescript希望我使用prepare,但我不需要在我的reducer中使用prepare。我的英雄Slice

const heroesSlice = createSlice({
  name: 'heroes',
  initialState,
  reducers: {
    toogleFavoriteHero: toggleStar,
    addFavoriteHeroes: {
      reducer(state, action) {
        console.log(state);
      },
    },
  },
  extraReducers: builder => {
    builder
      .addCase(fetchHeroes.fulfilled, (state, action) => {
        const arr = action.payload.sort(
          (
            firstAbility: { primary_attr: string },
            secondAbility: { primary_attr: string }
          ) => {
            return secondAbility.primary_attr.localeCompare(
              firstAbility.primary_attr
            );
          }
        );

        state.heroes = arr;
      })
      .addCase(fetchHeroes.rejected, (state, action) => {
        state.err = action.payload as string;
      });
  },
});

我在addFavoriteHeroes中遇到问题- vscode给出了此警告

Type "{ reducer(state: WritableDraft<IHeroes>, action: PayloadAction<any, string, any, any>): void; }" cannot be assigned to type "{ reducer(state: WritableDraft<IHeroes>, action: PayloadAction <any, string, any, any>): void;} & { prepare(...a: never[]): Omit<PayloadAction<any, string, any, any>, "type">; }".
   The property "prepare" is not present in type "{ reducer(state: WritableDraft<IHeroes>, action: PayloadAction<any, string, any, any>): void; }" and is required in type "{ prepare(...a: never[]): Omit<PayloadAction<any, string, any, any>, "type">; }".

我找到了一种解决方法,但是如果我只想console.log(state.heroes),我得到了这个,我不能以正常的方式使用它,我需要将其字符串化,然后解析,什么是不舒服的,我想应该用另一种方法在createSlice中使用reducer而不准备(){}

Proxy(Object) {i: 0, A: {…}, P: false, I: false, R: {…}, …}

我是说这边

const addHeroToFavorite: CaseReducer<typeof initialState> = (state, action) => {
  console.log(state.favoriteHeroes);
};

如果有人向我解释如何在createSlice中使用typescript创建reducer而不使用prepare(){},我将不胜感激。

ifsvaxew

ifsvaxew1#

在“自定义生成的动作创建器”文档中:
此对象必须包含两个属性:reducerprepare
如果不想指定prepare回调,可以直接将addHeroToFavorite reducer函数赋给reducers.addFavoriteHeroes属性。

const addHeroToFavorite: CaseReducer<typeof initialState> = (state, action) => {
    // console.log(state.favoriteHeroes);
    console.log(original(state)?.favoriteHeroes);
    return state;
};

const heroesSlice = createSlice({
    name: "heroes",
    initialState,
    reducers: {
        addFavoriteHeroes: addHeroToFavorite,
    },
});

此外,RTK在下面使用了immerjs,状态是草稿状态。这就是为什么你有一个代理对象。
要获取原始状态,可以使用original函数。

import { createSlice, CaseReducer, configureStore, original } from "@reduxjs/toolkit";

const initialState = {
    favoriteHeroes: [1, 2, 3],
};

const addHeroToFavorite: CaseReducer<typeof initialState> = (state, action) => {
    // console.log(state.favoriteHeroes);
    console.log(original(state)?.favoriteHeroes);
    return state;
};

const heroesSlice = createSlice({
    name: "heroes",
    initialState,
    reducers: {
        addFavoriteHeroes: {
            reducer: addHeroToFavorite,
            prepare: (hero) => {
                return { payload: hero };
            },
        },
    },
});

const store = configureStore({
    reducer: {
        heroes: heroesSlice.reducer,
    },
});

store.dispatch(heroesSlice.actions.addFavoriteHeroes(4));

codesandbox

相关问题