Back to snippets
redux_toolkit_createAsyncThunk_fetch_with_loading_states_typescript.ts
typescriptA standard Redux Toolkit slice using createAsyncThunk to fetch
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