我正在尝试使用Redux-toolkit
从两个不同的API获取数据,但我不希望同时获取它们。假设我有两个按钮,如果我点击button 1
,应用程序应该从第一个api获取数据,如果点击button 2
,数据应该来自第二个api。
另一件事是API有不同的结构,所以我需要两个不同的切片(或减速器(。问题是,由于我对两个减速器使用相同的存储,因此两个API都被提取。
import { configureStore, ThunkAction, Action } from '@reduxjs/toolkit'
import footballReducer from 'features/tournaments/footballSlice'
import volleyballReducer from 'features/tournaments/tournamentsSlice'
export const store = configureStore({
reducer: {
matchesFootball: footballReducer, // USED TO FETCH API 1
matchesVolleyball: volleyballReducer, // USED TO FETCH API 2
}
})
export type AppDispatch = typeof store.dispatch
export type RootState = ReturnType<typeof store.getState>
export type AppThunk<ReturnType = void> = ThunkAction<
ReturnType,
RootState,
unknown,
Action<string>
>
有没有一种方法可以控制将执行哪个减速器?
我最初的想法是:
1-使用两个不同的切片,每个API一个切片,并执行其各自的reducer(我不能确定最后一部分是否可能(
2-创建两个商店,这会让管理变得困难,因为我现在只有两个减速器,但它将增加到近10个;
3-只使用一个切片,其中我将为每个API数据设置一个extra reducer
,在这种情况下,我认为我必须为每个获取创建一个不同的函数;
有没有内置的方法可以做到这一点?或者至少是一种更直接的方式,看起来不会是什么坏把戏?
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "store/store";
import http from "services/services";
import IVolleyballModel from "models/VoleyballModel";
export interface VolleyballState {
matches: IVolleyballModel[]
status: "success" | "loading" | "failed"
rounds: number
tournamentName: string
}
const initialState: VolleyballState = {
matches: [],
status: "loading",
rounds: 0,
tournamentName: ''
};
export const fetchMatches = createAsyncThunk(
"matchesList/fetchMatches",
async (gender: number) => {
const response = await http.getSLTable(gender);
return response.data;
}
);
export const tournamentsSlice = createSlice({
name: "matchesList",
initialState,
reducers: {
setTournamentName (state, action: PayloadAction<string>) {
state.tournamentName = action.payload
}
},
extraReducers: (builder) => {
builder
.addCase(fetchMatches.pending, (state) => {
state.status = "loading";
})
.addCase(fetchMatches.fulfilled, (state, action) => {
state.status = "success";
let allMatches: any[] = [];
let rounds: number = 0;
action.payload.grupos[0].rodadas.map((round: { jogos: [] }) => {
// ... SOME LOGIC
});
state.matches = [...allMatches];
state.rounds = rounds;
})
.addCase(fetchMatches.rejected, (state) => {
state.status = "failed";
});
},
});
export const { setTournamentName } = tournamentsSlice.actions
export const getData = (state: RootState) => state.matchesVolleyball;
export default tournamentsSlice.reducer;
你完全可以做1.
-一个asyncThunk的extraReducer不会触发另一个async Thunk。
也就是说,您可能还想探索RTK查询,它将所有的获取、状态保持和存储逻辑抽象出来。
在这两种情况下,我建议您在官方Redux Essentials教程的第5章、第7章和第8章中阅读,该教程将引导您了解不同的方法,并展示两者的优缺点。