Nearby lessons
40 of 44🌀 Introduction to Redux
📌 Why Redux?
Why Redux?
React already provides ways to share data between components (using props and Context API). But when applications become large and complex, managing state and passing data gets harder. Redux solves this problem by making state management predictable, centralized, and easier to debug.
📌 How does data normally flow in React?
- In React, data flows in one direction → from parent to child using props.
- This is called unidirectional data flow.
⚠️ Problem with Prop Drilling
- If a deeply nested child needs data from a top-level parent, data must pass through all intermediate components.
- Even if middle components don’t use it, they must forward the data.
- This is called prop drilling and makes the code hard to maintain.
🔧 Using React Hooks (Context API & useContext)
- The Context API lets you create a global store to share data across components.
- The
useContexthook makes it easy to consume data anywhere in the tree. - Great for small apps, but can become messy in large-scale projects.
🚀 How Redux Solves the Problem
- Better suited when apps have complex state logic.
- Useful when many components need different parts of state.
- Allows easy debugging and tracking of state changes.
- Provides a centralized store where the entire app’s state lives.
- Components can directly access the state they need.
- State updates are predictable through reducers.
🔥 What is Redux?
Redux is a state management library and a pattern for updating application state.
- Uses actions to describe changes
- Maintains a centralized store
- State can only be updated predictably through reducers
🏗️ Main Concepts of Redux
- Action – What to do?
- Action Creator
- Reducer – How to do it?
- Store – Holds the State
Plain JS objects with a type field. They only describe what should happen, not how.
{
type: 'INCREMENT',
payload: num
}
Functions that return actions.
export const incNumber = (num) => ({
type: 'INCREMENT',
payload: num
});
Functions that take current state + action and return a new state.
const changeTheNumber = (state = 0, action) => {
switch(action.type) {
case "INCREMENT": return state + action.payload;
case "DECREMENT": return state - 1;
default: return state;
}
}
The store combines state, actions, and reducers. Only one store exists per Redux app.
import { createStore } from "redux";
const store = createStore(rootReducers);
✅ Redux Workflow (Step by Step)
- Action → Describes what should happen
- Reducer → Decides how the state should change
- Store → Holds the application state and connects everything
- Dispatch → Sends actions to reducers to update state
✨ In Simple Words
- Props → Good for simple apps, but leads to prop drilling
- Context API → Fixes prop drilling for small apps
- Redux → Best for large apps, predictable, centralized, and powerful
🧮 Example – Counter App with Redux
React Playground
import React from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { incNumber, decNumber } from './actions.jsx'; const App = () => { const myState = useSelector(state => state.changeTheNumber); const dispatch = useDispatch(); return ( <div className='container'> <h1>Increment/Decrement Counter</h1> <h4>using React and Redux</h4> <div className="quantity"> <a className="quantity_minus" onClick={() => dispatch(decNumber())}> <span>-</span> </a> <input type="text" value={myState} readOnly /> <a className="quantity_plus" onClick={() => dispatch(incNumber())}> <span>+</span> </a> </div> </div> ); } export default App;
🧠 Test Your Knowledge
4 QuestionsProgress: 0 / 4
Keep Going!React - Redux Toolkit