The Great Hook Showdown: useState 🆚 useReducer
Udit Kumar / February 08, 2022
3 min read • ––– views
Hey 👋 there React enthusiasts! Are you tired 😩 of trying to decide whether to use useState
or useReducer
in your components? Well, have no fear because I'm here to help you make that decision 🤙.
First things first, let's define these two hooks. useState
is a hook that allows you to add state to functional components. It returns an array with two items: the current state value and a function to update it. On the other hand, useReducer
is also a hook that allows you to add state to functional components, but it takes in a reducer function and returns the current state and a dispatch function.
Now, the question is: when should you use useState
and when should you use useReducer
?
Well, the general rule of thumb is that if you have simple state logic, then you should use useState
. For example, if you just need to keep track of a boolean value or a string, useState
is the way to go.
For example, let's say you want to keep track of whether a user is logged in or not. You can do this by using useState
:
jsximport React, { useState } from 'react';
const App = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<div>
<button onClick={() => setIsLoggedIn(!isLoggedIn)}>
{isLoggedIn ? 'Log out' : 'Log in'}
</button>
</div>
);
};
On the other hand, if you have complex state logic that requires multiple updates or performing calculations based on the previous state, then useReducer
is the hook for you. It's like a mini Redux store within your component, allowing you to manage your state more efficiently.
Like if you want to keep track of a user's shopping cart. You can do this by using useReducer
:
jsximport React, { useReducer } from 'react';
const initialState = {
items: [],
total: 0
};
const reducer = (state, action) => {
switch (action.type) {
case 'ADD_ITEM':
return {
...state,
items: [...state.items, action.payload],
total: state.total + action.payload.price
};
case 'REMOVE_ITEM':
return {
...state,
items: state.items.filter((item) => item.id !== action.payload.id),
total: state.total - action.payload.price
};
default:
return state;
}
};
const App = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<button
onClick={() =>
dispatch({ type: 'ADD_ITEM', payload: { id: 1, price: 10 } })
}
>
Add item
</button>
<button
onClick={() =>
dispatch({ type: 'REMOVE_ITEM', payload: { id: 1, price: 10 } })
}
>
Remove item
</button>
</div>
);
};
But wait, there's more! If you find yourself using multiple useState
calls to manage your state, it might be a good idea to consider using useReducer
instead. This is because useReducer
allows you to centralize your state updates in a single function, making your code more organized and easier to read.
So, to sum it up: useState
for simple state updates and useReducer
for complex state logic and multiple updates.
But remember, these are just general guidelines. The most important thing is to choose the hook that best fits your needs and makes your code more readable and maintainable.
And that's it, folks! I hope this helps you make the right decision when it comes to useState
vs useReducer
. Happy coding!
If you have any questions or comments, feel free to reach out to me on Twitter or LinkedIn. I'd love to hear from you!