
React State Hooks
āļø The First React Hook
State is the first concept you'll learn about React. It is what makes React dynamic.
Click a button, the UI updates.
Type in a form, the value appears.
Fetch data, the screen reflects it.
In this guide, you'll learn the hooks that made this possible.
ā useState ā useReducer ā Updating objects and arrays ā Choosing between them
#react #hooks #usestate #usereducer #state #webdev #frontend #coding #tips
States are variables in a React component that trigger re-renders when they change. They are local to the component and can be updated with hooks.
The hooks used to manage the states are called state hooks. The most common ones are useState and useReducer.
useState is for simple state management, while useReducer is for complex state logic.
useState
Add local state to a component. Returns the current value and a setter function.
const [count, setCount] = useState(0);count is the current state value, and setCount is a function to update it. The initial value is set to 0 in this example.
Updating state
Replace the state with a new value.
setCount(5);
// count is now 5, component re-rendersUse the functional updater when the new state depends on the previous state.
setCount((prev) => prev + 1);
// count is incremented by 1, component re-rendersLazy initialization
Pass a function to compute the initial state only once, on the first render.
const [todos, setTodos] = useState(() => loadFromLocalStorage());Updating objects
When working with objects, always create a new object instead of mutating the existing one.
const [user, setUser] = useState({ name: "Ada", age: 30 });
setUser({ ...user, age: 31 });Updating arrays
Similarly, when working with arrays, create a new array instead of mutating. Use map, filter, and spread.
const [items, setItems] = useState([1, 2, 3]);
setItems([...items, 4]); // add
setItems(items.filter((n) => n !== 2)); // remove
setItems(items.map((n) => (n === 2 ? 20 : n))); // updateuseReducer
Manage complex state logic with a reducer function. Returns the current state and a dispatch function.
const [state, dispatch] = useReducer(reducer, { count: 0 });state is the current state variable.
dispatch is a function that takes an action object and updates the state based on the reducer logic.
reducer is a pure function that takes the current state and an action, and returns the next state.
{ count: 0 } is an example initial state.
The reducer function
The reducer function takes the current state and an action, and returns the next state.
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
case "reset":
return { count: 0 };
default:
throw new Error("Unknown action");
}
}Dispatching actions
Call dispatch with an action object to update the state.
dispatch({ type: "increment" });When this dispatch() is called, state will be updated according to the logic defined in the reducer function:
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
case "reset":
return { count: 0 };
default:
throw new Error("Unknown action");
}
}Lazy initialization
Pass a third argument to compute the initial state.
const [state, dispatch] = useReducer(reducer, initialArg, init);useState vs useReducer
Use useState when | Use useReducer when |
|---|---|
| State is simple (few values). | State has multiple sub-values. |
| Updates are independent. | Updates depend on each other. |
| Logic lives in the component. | You want to extract and test the logic. |
Full-Stack AI Developer Roadmap
From HTML & CSS to working with AI models, all in one structured roadmap.