Fetching Data with createAsyncThunk
Showcase how to define and use a createAsyncThunk action to fetch data from an API and dispatch the result to the Redux store.
// Define the async action using createAsyncThunk
export const fetchUserById = createAsyncThunk(
'users/fetchByIdStatus',
async (userId, { rejectWithValue }) => {
try {
const response = await fetch(`https://reqres.in/api/users/${userId}`);
if (!response.ok) {
throw new Error('Server Error!');
}
const data = await response.json();
return data.data;
} catch (error) {
return rejectWithValue(error.message);
}
}
);
This code defines an async action called fetchUserById that fetches data from an API and handles the possible promise states. It uses createAsyncThunk from Redux Toolkit, which takes the action type string and a payload creator callback. The callback performs the async operation using fetch and returns the data or a rejection value if the operation fails.
// Slice Reducer
const usersSlice = createSlice({
name: 'users',
initialState: {
entities: [],
loading: 'idle',
error: null
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUserById.pending, (state) => {
state.loading = 'loading';
})
.addCase(fetchUserById.fulfilled, (state, action) => {
state.loading = 'succeeded';
state.entities.push(action.payload);
})
.addCase(fetchUserById.rejected, (state, action) => {
state.loading = 'failed';
state.error = action.payload;
});
}
});
This code snippet outlines how a slice reducer can handle the states of the fetchUserById async action using extraReducers. It updates the loading status and stores the user data or error message accordingly.
// Dispatch the async action
// This would typically be done inside of a React component's effect hook, or in response to a user action like clicking a button
dispatch(fetchUserById(123));
This code dispatches the fetchUserById async action with an example user ID (123). It should be called inside a React component, often as a result of an effect or a user action.