【问题标题】:How to use two different slices with Redux-toolkit?如何在 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;

【问题讨论】:

    标签: javascript reactjs redux redux-thunk redux-toolkit


    【解决方案1】:

    您完全可以做到1. - 一个 asyncThunk 的 extraReducer 不会为另一个 asyncThunk 触发。

    也就是说,您可能还想探索 RTK-Query,它将所有获取、状态保持和存储逻辑从您手中抽象出来。

    在这两种情况下,我建议您阅读the official Redux Essentials tutorial 的第 5、7 和 8 章,了解不同的方法并展示两者的优缺点。

    【讨论】:

    • 是的,我试图通过阅读文档来解决这个问题,但我在截止日期前,所以我选择了3,这是目前最简单的方法。我再设置一个参数,让服务脚本决定调用哪个 API。但我一定会听从您的建议并深入研究它。谢谢。
    猜你喜欢
    • 2021-01-24
    • 2020-10-08
    • 2021-02-06
    • 2020-04-14
    • 1970-01-01
    • 2021-12-05
    • 2021-05-24
    • 2021-10-08
    • 2021-07-26
    相关资源
    最近更新 更多