How to manage Loading & Error States when Fetching Data in Redux ?
Last Updated :
26 Apr, 2024
This article is about managing loading states and error states when fetching data in redux. I have used an API that returns a list of users. I will be using this API and redux to manage the loading states and error states.
Final Output
Prerequisites:
Approach:
- Install the required packages, we are using axios to fetch data, react-redux and redux-tool kit , so install these packages.
- We are using two components app.js and userComponent.jsx which renders list of users from the api.
- We have redux store to manage the state and userSlice to handle and manage the users state.
Steps to create the project:
Step1: create the react app using the command
npx create-react-app react-loading-states
cd react-loading-states
Step2: Install the required dependencies
npm i axios
npm install @reduxjs/toolkit
npm install react-redux
Project Structure:
Project Structure
The updated dependencies in package.json file looks like
project-dependencies
Example: To demonstrate managing loading states and error states while fetching data using react-redux
CSS
/* App.css */
.nav{
display: flex;
align-items: center;
padding-left: 3vw;
color: white;
height: 8vh;
background-color: rgb(83, 88, 105);
}
JavaScript
//App.js
import logo from "./logo.svg";
import "./App.css";
import UserComponent from "./user/UserComponent";
function App() {
return (
<div>
<div className="nav">
<p>Home</p>
</div>
<UserComponent />
</div>
);
}
export default App;
JavaScript
//userComponent.jsx
import React from 'react'
import { useDispatch, useSelector } from 'react-redux';
import { useEffect } from 'react';
import { fetchUsers } from './userSlice';
function UserComponent() {
const dispatch = useDispatch();
const user = useSelector((state) => state.user);
useEffect(() => {
dispatch(fetchUsers())
console.log("users", user)
}, [])
return (
<div>
<h2>ALL USERS DETAILS</h2>
{user?.loading && <div> loading....</div>}
{!user?.loading && user?.users?.length > 0 ?
<div>
<thead>
<tr>
<td><h4>Name</h4></td>
<td><h4>Email</h4></td>
<td><h4>UserName</h4></td>
</tr>
</thead>
<tbody>
{user?.users?.map((item) => (
<tr>
<td>{item?.name}</td>
<td>{item?.email}</td>
<td>{item?.username}</td>
</tr>
))}
</tbody>
</div> : <div>NO USER DATA AVAILABLE</div>
}
</div>
)
}
export default UserComponent
JavaScript
//userSlice.js
import { createSlice } from "@reduxjs/toolkit";
import { createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
const initialState = {
loading: false,
users: [],
error: "",
};
export const fetchUsers = createAsyncThunk("FETCH_USERS", async () => {
return axios
.get("https://jsonplaceholder.typicode.com/users")
.then((response) => response.data.map((user) => user));
});
const userSlice = createSlice({
name: "user",
initialState,
extraReducers: (builder) => {
builder.addCase(fetchUsers.pending, (state) => {
state.loading = true;
});
builder.addCase(fetchUsers.fulfilled, (state, action) => {
state.loading = false;
state.users = action.payload;
state.error = "";
});
builder.addCase(fetchUsers.rejected, (state, action) => {
state.loading = false;
state.users = [];
state.error = action.error.message;
});
},
});
export default userSlice.reducer;
JavaScript
//store.js
import { configureStore } from "@reduxjs/toolkit";
import userReducer from "../user/userSlice";
const store = configureStore({
reducer: {
user: userReducer,
},
});
export default store;
JavaScript
//index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import store from "./store/store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
To start the project
npm start
Output:
Final Output
Share your thoughts in the comments
Please Login to comment...