Introduction
In the previous article, we learned:
File uploads
Multer
Cloudinary integration
Image handling
FormData
Media storage systems
Now it is time to learn one of the most important concepts in large React applications:
State Management
As applications grow larger, managing data between multiple components becomes difficult.
Examples:
User authentication
Shopping cart
Theme settings
Notifications
User profile data
Passing data manually through many components becomes messy.
To solve this problem, React applications use:
Context API
Redux Toolkit
In this article, we will learn:
What state management is
Local vs global state
Context API
useContext Hook
Redux Toolkit
Redux store
Actions and reducers
Managing authentication globally
What is State?
State means:
Data that changes dynamically
Examples:
Counter value
Logged-in user
Theme color
API response data
What is State Management?
State management means:
Managing and sharing application data efficiently
Local State vs Global State
| Local State | Global State |
|---|---|
| Used in one component | Used across app |
| useState() | Context / Redux |
| Small data | Large shared data |
Problems Without State Management
Suppose authentication data is needed in:
Navbar
Dashboard
Profile page
Sidebar
Passing props repeatedly creates:
Props Drilling
What is Props Drilling?
Props drilling means:
Passing props through multiple unnecessary components
Example:
App
↓
Dashboard
↓
Sidebar
↓
Profile
This becomes difficult to manage.
What is Context API?
React Context helps share data globally without props drilling.
Why Context API is Useful
Context API helps:
Share authentication
Manage themes
Store user data
Avoid repeated props
Creating Context Folder
Inside React project:
src
│
├── context
Creating Auth Context
Create:
AuthContext.js
Basic Context Setup
import {
createContext,
useState
} from 'react';
export const AuthContext = createContext();
function AuthProvider({ children }) {
const [isAuthenticated,
setIsAuthenticated] = useState(false);
return (
<AuthContext.Provider
value={{
isAuthenticated,
setIsAuthenticated
}}
>
{children}
</AuthContext.Provider>
);
}
export default AuthProvider;
Understanding createContext()
createContext()
creates global data storage.
Understanding Provider
<AuthContext.Provider>
shares data with all components.
Wrapping App with Provider
Inside:
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import AuthProvider from './context/AuthContext';
const root = ReactDOM.createRoot(
document.getElementById('root')
);
root.render(
<AuthProvider>
<App />
</AuthProvider>
);
Using Context Data
React provides:
useContext()
Example
import {
useContext
} from 'react';
import {
AuthContext
} from './context/AuthContext';
function Navbar() {
const {
isAuthenticated
} = useContext(AuthContext);
return (
<div>
{
isAuthenticated
? 'Logged In'
: 'Guest'
}
</div>
);
}
How Context API Works
Provider Stores Data
↓
Components Access Data
↓
UI Updates Automatically
Limitations of Context API
Context API works well for:
Small applications
Medium applications
But large enterprise applications often use:
Redux
What is Redux?
Redux is a powerful global state management library.
Why Redux is Popular
Redux helps:
Manage large state
Organize application logic
Debug easily
Scale applications
What is Redux Toolkit?
Redux Toolkit simplifies Redux development.
Old Redux required:
Too much boilerplate code
Complex setup
Redux Toolkit solves these problems.
Installing Redux Toolkit
Inside client folder:
npm install @reduxjs/toolkit react-redux
Understanding Packages
| Package | Purpose |
|---|---|
| @reduxjs/toolkit | Redux setup |
| react-redux | Connect React with Redux |
Redux Core Concepts
| Concept | Meaning |
|---|---|
| Store | Global state |
| Action | What happened |
| Reducer | Updates state |
| Dispatch | Sends action |
Understanding Redux Flow
Component
↓
Dispatch Action
↓
Reducer
↓
Store Updated
↓
UI Re-render
Creating Redux Folder Structure
src
│
├── app
├── features
Creating Store
Create:
app/store.js
Redux Store Setup
import {
configureStore
} from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {}
});
What is configureStore()?
configureStore()
creates Redux store.
What is a Slice?
Redux Toolkit uses:
Slices
A slice contains:
State
Reducers
Actions
Creating Auth Slice
Create:
features/authSlice.js
Example Auth Slice
import {
createSlice
} from '@reduxjs/toolkit';
const initialState = {
isAuthenticated: false
};
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
login: (state) => {
state.isAuthenticated = true;
},
logout: (state) => {
state.isAuthenticated = false;
}
}
});
export const {
login,
logout
} = authSlice.actions;
export default authSlice.reducer;
Understanding createSlice()
createSlice()
automatically creates:
Reducers
Actions
Adding Reducer to Store
import authReducer from
'../features/authSlice';
export const store = configureStore({
reducer: {
auth: authReducer
}
});
Connecting Redux with React
Inside:
src/index.js
import { Provider } from 'react-redux';
import { store } from './app/store';
root.render(
<Provider store={store}>
<App />
</Provider>
);
Using Redux State
React Redux provides:
useSelector()
Example
import {
useSelector
} from 'react-redux';
function Navbar() {
const isAuthenticated = useSelector(
(state) => state.auth.isAuthenticated
);
return (
<h1>{isAuthenticated ? 'User' : 'Guest'}</h1>
);
}
Updating Redux State
React Redux provides:
useDispatch()
Example Login Action
import {
useDispatch
} from 'react-redux';
import {
login
} from './features/authSlice';
function Login() {
const dispatch = useDispatch();
return (
<button
onClick={() => dispatch(login())}
>
Login
</button>
);
}
Redux Authentication Flow
User Logs In
↓
Dispatch login Action
↓
Redux Store Updates
↓
All Components Update
Context API vs Redux
| Context API | Redux Toolkit |
|---|---|
| Simple setup | More scalable |
| Small projects | Large projects |
| Built into React | External library |
| Less boilerplate | Powerful architecture |
When to Use Context API
Use Context API for:
Themes
Authentication
Language settings
When to Use Redux
Use Redux for:
Large applications
Complex API data
Shopping carts
Dashboards
Enterprise apps
Best Practices
Keep State Organized
Separate:
Auth state
User state
Product state
Avoid Unnecessary Global State
Not every data belongs in Redux.
Use Redux Toolkit
Modern Redux development should always use:
Redux Toolkit
Create Separate Slices
Example:
authSlice
productSlice
cartSlice
Common Beginner Mistakes
Storing Everything in Redux
Only global data should use Redux.
Mutating State Incorrectly
Redux Toolkit handles immutable updates automatically.
Forgetting Provider
Without:
<Provider>
Redux will not work.
Real-World Applications
Redux is used in:
E-commerce websites
Banking dashboards
Social media apps
SaaS platforms
Learning management systems
Conclusion
You have now learned advanced state management in React using:
Context API
Redux Toolkit
You learned:
Global state management
Redux store
Actions
Reducers
Slices
Authentication management
useSelector()
useDispatch()
Now your React applications are becoming scalable, organized, and enterprise-ready.
Comments
Post a Comment