简体   繁体   中英

How to use two different slices with Redux-toolkit?

I'm trying to fetch data from two different API's using Redux-toolkit , however I don't want them to be fetched simultaneously. Let's say I have two buttons and if I click on the button 1 the app should fetch data from the first api and if the click is on the button 2 the data should come from the second API.

Other thing is that the API's have different structures, so I need two different slices (or reducers). The issue is, since I'm using the same store for both reducers, both API's are being fetched.

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>
>

Is there a way where I can control which reducer will be executed?

My first thoughts were:

1- Use two different slices, one for each API and execute its respective reducer (I couldn't be sure if this last part is possible)

2- To create two stores, what would make it hard to manage, since I have only two reducers for now, but it'll increase to almost 10;

3- Use only one slice, where I would set one extra reducer for each API data, in that case I believe I would have to create one different function for each fetch;

Is there a builtin way to do that? Or at least a more straightforward way, which wouldn't look like some bad trick?

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;

You can totally do 1. - an extraReducer for one asyncThunk will not trigger for another asyncThunk.

That said, you might also want to explore RTK-Query, which abstracts all that fetching, state keeping and storing logic away from you.

In both cases, I would recommend you read up on it in Chapters 5, 7 and 8 of the official Redux Essentials tutorial that walks you through the different approaches and shows benefits and drawbacks of both.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM