如何在 Redux-toolkit 中使用两个不同的切片?
Posted
技术标签:
【中文标题】如何在 Redux-toolkit 中使用两个不同的切片?【英文标题】:How to use two different slices with Redux-toolkit? 【发布时间】:2022-01-18 22:10:39 【问题描述】:我正在尝试使用Redux-toolkit
从两个不同的 API 获取数据,但是我不希望同时获取它们。假设我有两个按钮,如果我点击 button 1
,应用程序应该从第一个 api 获取数据,如果点击的是 button 2
,数据应该来自第二个 API。
另外一点是 API 有不同的结构,所以我需要两个不同的切片(或化简器)。问题是,由于我为两个 reducer 使用同一个 store,所以两个 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>
>
有没有办法可以控制执行哪个reducer?
我的第一个想法是:
1- 使用两个不同的切片,一个用于每个 API 并执行其各自的 reducer(我不确定最后一部分是否可行)
2- 创建两个store,什么地方不好管理,因为我现在只有两个reducer,但是会增加到差不多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】:您完全可以做到1.
- 一个 asyncThunk 的 extraReducer 不会为另一个 asyncThunk 触发。
也就是说,您可能还想探索 RTK-Query,它将所有获取、状态保持和存储逻辑从您手中抽象出来。
在这两种情况下,我建议您阅读the official Redux Essentials tutorial 的第 5、7 和 8 章,了解不同的方法并展示两者的优缺点。
【讨论】:
是的,我试图通过阅读文档来解决这个问题,但我在截止日期前,所以我选择了3
,这是目前最简单的方法。我再设置一个参数,让服务脚本决定调用哪个 API。但我一定会听从您的建议并深入研究它。谢谢。以上是关于如何在 Redux-toolkit 中使用两个不同的切片?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Storybook 中使用 redux-toolkit?
如何将 redux-toolkit createSlice 与 React 类组件一起使用
如何使用 redux-toolkit 动态更改基本 URL?