Home > Software design >  How to reload data from api in Redux
How to reload data from api in Redux

Time:12-07

when I lose in a hangman I want to reload my data in the API so that a new password appears. Unfortunately I have no idea how to reload it without reloading the whole page, is it even possible to run the api again on a button click for example?

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

const url = 'https://random-word-api.herokuapp.com/word?number=1';

const initialState = {
    password: '1',
    misstake: 0,
    usedChart: [],
};

export const getPassword = createAsyncThunk(
    'hangman/getPassword',
    async (thunkAPI) => {
        console.log(1)
        try {
            const resp = await axios(url)
            return resp.data
        } catch(error){
            return thunkAPI.rejectWithValue('api not working');
        }
    }
);

const HangManSlice = createSlice({
    name: 'hangman',
    initialState,
    reducers: {
        increaseError: (state) => {
            state.misstake  = 1
        },
        usedCharts: (state, action) => {
            state.usedChart.push(action.payload)
        },
        restart: (state) => {
            state.misstake = 0
            state.usedChart = []
            getPassword()
        }
    },
    extraReducers: (builder) => {
        builder
            .addCase(getPassword.fulfilled, (state, action) => {
                state.password = action.payload;
            })
    }
})

export const { increaseError, usedCharts, restart } = HangManSlice.actions

export default HangManSlice.reducer

CodePudding user response:

You should dispatch the getPassword() from the "restart" button handler instead of calling it your reducer.

const RestartButton = () => {
  const dispatch = useDispatch();

  const restartHandler = () => {
    dispatch(getPassword());
    dispatch(restart())
  };
 
  return (
    <button onClick={restartHandler}>Restart</button>
  );
}

Another option is to use the getPassword thunk to initialize a new game like so:

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

const url = 'https://random-word-api.herokuapp.com/word?number=1';

const initialState = {
    loading: false,
    password: '1',
    misstake: 0,
    usedChart: [],
};

export const startGame = createAsyncThunk(
    'hangman/getPassword',
    async (thunkAPI) => {
        console.log(1)
        try {
            const resp = await axios(url)
            return resp.data
        } catch(error){
            return thunkAPI.rejectWithValue('api not working');
        }
    }
);

const HangManSlice = createSlice({
    name: 'hangman',
    initialState,
    reducers: {
        increaseError: (state) => {
            state.misstake  = 1
        },
        usedCharts: (state, action) => {
            state.usedChart.push(action.payload)
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(startGame.pending, (state, action) => {
                state.loading = true;
            })
            .addCase(startGame.rejected, (state, action) => {
                state.loading = false;
            })
            .addCase(startGame.fulfilled, (state, action) => {
                state.loading = false;

                // store new password
                state.password = action.payload;

                // reset state
                state.misstake = 0
                state.usedChart = []
            })
    }
})

export const { increaseError, usedCharts, restart } = HangManSlice.actions

export default HangManSlice.reducer

Now you can dispatch startGame(), and the state will be reset with a new password.

  • Related