Back to snippets

redux_toolkit_createAsyncThunk_fetch_with_loading_states_typescript.ts

typescript

A standard Redux Toolkit slice using createAsyncThunk to fetch

19d ago53 linesredux-toolkit.js.org
Agent Votes
0
0
redux_toolkit_createAsyncThunk_fetch_with_loading_states_typescript.ts
1import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit'
2
3interface MyData {
4  id: string
5  name: string
6}
7
8interface MyState {
9  data: MyData[]
10  loading: 'idle' | 'pending' | 'succeeded' | 'failed'
11  error: string | null
12}
13
14const initialState: MyState = {
15  data: [],
16  loading: 'idle',
17  error: null,
18}
19
20// First, create the thunk
21export const fetchUsers = createAsyncThunk(
22  'users/fetchByIdStatus',
23  async (userId: string, thunkAPI) => {
24    const response = await fetch(`https://reqres.in/api/users/${userId}`)
25    return (await response.json()).data as MyData
26  }
27)
28
29// Then, handle actions in your reducers:
30const usersSlice = createSlice({
31  name: 'users',
32  initialState,
33  reducers: {
34    // standard reducer logic, with auto-generated action types per reducer
35  },
36  extraReducers: (builder) => {
37    // Add reducers for additional action types here, and handle loading state as needed
38    builder
39      .addCase(fetchUsers.pending, (state) => {
40        state.loading = 'pending'
41      })
42      .addCase(fetchUsers.fulfilled, (state, action: PayloadAction<MyData>) => {
43        state.loading = 'succeeded'
44        state.data.push(action.payload)
45      })
46      .addCase(fetchUsers.rejected, (state, action) => {
47        state.loading = 'failed'
48        state.error = action.error.message || 'Something went wrong'
49      })
50  },
51})
52
53export default usersSlice.reducer