Saltar al contenido

¿Cómo usar Redux-Thunk con createSlice de Redux Toolkit?

Solución:

Soy un mantenedor de Redux y creador de Redux Toolkit.

FWIW, nada sobre hacer llamadas asíncronas con cambios de Redux con Redux Toolkit.

Seguiría usando un middleware asíncrono (normalmente redux-thunk), recupera datos y envía acciones con los resultados.

A partir de Redux Toolkit 1.3, tenemos un método auxiliar llamado createAsyncThunk que genera los creadores de acciones y solicita el envío de acciones de ciclo de vida para usted, pero sigue siendo el mismo proceso estándar.

Este código de muestra de los documentos resume el uso;

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { userAPI } from './userAPI'

// First, create the thunk
const fetchUserById = createAsyncThunk(
  'users/fetchByIdStatus',
  async (userId, thunkAPI) => {
    const response = await userAPI.fetchById(userId)
    return response.data
  }
)

// Then, handle actions in your reducers:
const usersSlice = createSlice({
  name: 'users',
  initialState: { entities: [], loading: 'idle' },
  reducers: {
    // standard reducer logic, with auto-generated action types per reducer
  },
  extraReducers: {
    // Add reducers for additional action types here, and handle loading state as needed
    [fetchUserById.fulfilled]: (state, action) => {
      // Add user to the state array
      state.entities.push(action.payload)
    }
  }
})

// Later, dispatch the thunk as needed in the app
dispatch(fetchUserById(123))

Consulte la página de documentos de Redux Toolkit “Guía de uso: Lógica asíncrona y obtención de datos” para obtener información adicional sobre este tema.

¡Con suerte, eso te indicará la dirección correcta!

Usar redux-toolkit v1.3.0-alpha.8

Prueba esto

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

export const myAsyncInSlice = createAsyncThunk('bundles/myAsyncInSlice', () =>
  getAxiosInstance()
    .get("https://foroayuda.es/")
    .then(ok => ok.data)
    .catch(err => err),
);

const usersSlice = createSlice({
  name: 'bundles',
  initialState: {
    bundles: [],
    selectedBundle: null,
    page: {
      page: 0,
      totalElements: 0,
      size: 20,
      totalPages: 0,
    },
    myAsyncResponse: null,
    myAsyncResponseError: null,
  },
  reducers: {
    // add your non-async reducers here
  },
  extraReducers: {
    // you can mutate state directly, since it is using immer behind the scenes
    [myAsyncInSlice.fulfilled]: (state, action) => {
      state.myAsyncResponse = action.payload;
    },
    [myAsyncInSlice.rejected]: (state, action) => {
      state.myAsyncResponseError = action.payload;
    },
  },
});


Puedes usar createAsyncThunk crear thunk action, que puede activarse mediante dispatch

teamSlice.ts

import {
  createSlice,
  createAsyncThunk,
} from "@reduxjs/toolkit";
const axios = require('axios');

export const fetchPlayerList = createAsyncThunk('team/playerListLoading', 
  (teamId:string) =>
  axios
    .get(`https://api.opendota.com/api/teams/${teamId}/players`)
    .then(response => response.data)
    .catch(error => error),
);

const teamInitialState = {
   playerList: {
     status: 'idle',
     data: {},
     error: {}
   }    
};

const teamSlice = createSlice({
  name: 'user',
  initialState: teamInitialState,
  reducers: {},
  extraReducers: {
    [fetchPlayerList.pending.type]: (state, action) => {
        state.playerList = {
        status: 'loading',
        data: {},
        error: {}
      };
    },
    [fetchPlayerList.fulfilled.type]: (state, action) => {
        state.playerList = {
        status: 'idle',
        data: action.payload,
        error: {}
     };
    },
    [fetchPlayerList.rejected.type]: (state, action) => {
        state.playerList = {
        status: 'idle',
        data: {},
        error: action.payload,
      };
    },
  }
});

export default teamSlice;

Componente Team.tsx

import React from "react";
import { useSelector, useDispatch } from "react-redux";

import { fetchPlayerList } from './teamSlice';

const Team = (props) => {
  const dispatch = useDispatch();
  const playerList = useSelector((state: any) => state.team.playerList);

  return (
    <div>
      <button
        onClick={() => { dispatch(fetchPlayerList('1838315')); }}
      >Fetch Team players</button>

      <p>API status {playerList.status}</p>
      <div>
        { (playerList.status !== 'loading' && playerList.data.length) &&
          playerList.data.map((player) => 
            <div style={{display: 'flex'}}>
              <p>Name: {player.name}</p>
              <p>Games Played: {player.games_played}</p>
            </div>
          )
        }
      </div>
    </div>
  )
}

export default Team;
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *