Today was one of those days where learning doesn’t feel smooth.
It feels heavy.
I decided to properly sit with the useReducer hook and not just watch tutorials or read definitions. To do that, I built a small date counter project where I could increase/decrease days, change step size, and reset everything.
Simple UI.
Not-so-simple thinking.
And that’s exactly the point.
Why useReducer Exists (And Why It’s a Pro-Level Hook)
One thing became very clear to me today:
useReducer is a pro-level hook.
Not because it is fancy.
But because it changes the way you think about state.
It is not meant for simple counters or small forms. It is meant for complex state logic where:
- Many pieces of state are related
- Many events can update the same state
- You want one central place that controls all state transitions
The course also emphasized this:
useReducer is an advanced hook that can make complex logic much easier — but only if you understand the mental model.
At first, it looks scary.
But then I realized something important:
useReducer actually feels like a mix of old classic React and modern React.
- The structure feels a bit like old class components
- The usage feels like modern functional React
And because I already spent time fighting with class components, this didn’t feel completely alien.
It felt… structured.
The Mental Model (With a Real-World Example That Finally Made It Click)
Here is the analogy that finally made everything clear to me:
Imagine you want to withdraw money.
If you want to withdraw $10:
- You go to an ATM
- Insert your card
- Get your money
- Done
This is like useState:
Simple and direct.
But if you want to withdraw $5000:
- You go inside the bank
- You talk to the staff
- You give your account details
- You request the amount
- The bank system processes it
- Then you get the money
This is like useReducer.
You don’t directly change the state.
You send a request (action).
That request goes into a system (reducer).
And the system decides:
“Okay, this is how state should change.”
In code, instead of doing this:
setCount(count + step);
You do this:
dispatch({ type: "inc" });
And the reducer decides:
function reducer(state, action) {
switch (action.type) {
case "inc":
return { ...state, count: state.count + state.step };
case "setStep":
return { ...state, step: action.payload };
case "reset":
return initialState;
default:
throw new Error("Unknown action");
}
}
This is a completely different mental model.
And yes — it feels heavier.
But it is also more controlled, more predictable, and more scalable.
The Honest Truth
I won’t lie:
useReducer is not easy to understand at first.
It feels:
- Verbose
- Abstract
- Overkill for small things
But now I see its real purpose:
useReducer is not about writing less code.
It is about writing safer and more organized code.
Today I didn’t just build a small date counter.
I built respect for this hook.
I also realized why the course calls it advanced and professional-level.
I’m still learning it.
I’m still practicing it.
But at least now:
- The fear is gone
- The mental model is clear
- And I know exactly why it exists
Still learning.
Top comments (2)
nice one, usama! 💯
"Still learning." - me too ✨
thanks💖