useState is a React Hook used to add state to a function component. State represents information that can change over time and whose changes may require the component UI to update.
1 Basic Syntax
const [count, setCount] = useState(0);
The first value is the current state and the second value is the state setter. The argument passed to useState is the initial state.
2 State Update
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>
Increase
</button>
</div>
);
}
Calling setCount requests a state update. React then schedules the component to render again using the new state.
3 State Updates Are Not Direct Mutation
You should not directly change a state variable.
// Incorrect
count = count + 1;
Use the setter:
setCount(count + 1);
4 Functional Updates
When the next state depends on the previous state, use the functional updater form.
setCount(previous => previous + 1);
This is especially useful when several state updates may be scheduled based on the same previous state.
5 Updating Objects
Objects in state should normally be replaced with a new object rather than mutated.
const [user, setUser] = useState({
name: "John",
age: 30
});
setUser(previous => ({
...previous,
age: 31
}));
The spread operator copies the existing properties and the new age value replaces the old one.
6 Updating Nested Objects
Nested objects require copying each level that is being changed.
const [profile, setProfile] = useState({
name: "John",
address: {
city: "Bengaluru",
country: "India"
}
});
setProfile(previous => ({
...previous,
address: {
...previous.address,
city: "Mysuru"
}
}));
7 Updating Arrays
Arrays should also be updated by creating a new array.
const [items, setItems] = useState([]);
setItems(previous => [
...previous,
{ id: 1, name: "React" }
]);
Remove an Item
setItems(previous =>
previous.filter(item => item.id !== id)
);
Update an Item
setItems(previous =>
previous.map(item =>
item.id === id
? { ...item, completed: true }
: item
)
);
8 State Update Flow
flowchart TD
A[User Interaction] --> B[Call State Setter]
B --> C[React Schedules Update]
C --> D[Component Renders Again]
D --> E[New State Is Available]
E --> F[UI Reflects State]
9 Lazy Initial State
If calculating the initial state is expensive, a function can be passed to useState so React can use the initializer when establishing the initial state.
const [data, setData] = useState(() => expensiveCalculation());
This is different from calling the function immediately:
const [data, setData] = useState(expensiveCalculation());
The first form passes an initializer function. The second form executes the calculation while evaluating the component code.
10 State Initialization and Render
The initial state is used when the state is initialized. Changing the value passed to useState on later renders does not reset existing state automatically.
11 Multiple State Variables
A component can have multiple state variables.
const [name, setName] = useState("");
const [age, setAge] = useState(0);
const [isActive, setIsActive] = useState(false);
Separate state variables can make independent pieces of state easier to understand. If several values always change together and form one logical state object, an object or reducer may be more appropriate.
12 Common Mistakes
- Mutating objects or arrays directly.
- Forgetting to copy nested objects when updating nested state.
- Using the current state value instead of a functional updater when multiple updates depend on previous state.
- Storing data in state that can be calculated from other state.
- Assuming changing the initial value passed to
useStateresets the state. - Putting unrelated data into one very large state object.
13 Interview Questions
- What does
useStatereturn? - Does calling a state setter immediately change the current render's state variable?
- Why should state objects be treated as immutable?
- How do you update an object in state?
- How do you add, remove, and update items in a state array?
- When should you use a functional state update?
- What is lazy state initialization?
- Does changing the initial value of
useStatereset state on every render? - Can a component have multiple
useStatecalls? - When might
useReducerbe more suitable than many state variables?
14 Key Takeaways
useStateadds state to function components.- Use the setter instead of directly mutating state.
- Use functional updates when the next value depends on the previous value.
- Update objects and arrays immutably.
- Use lazy initialization when initial state calculation is expensive.
- Keep state minimal and avoid unnecessary duplicate state.
Conclusion
useState is one of the most frequently used React Hooks. The important interview concepts are state updates, immutable object and array updates, functional setters, lazy initialization, and understanding that state is associated with the component's render lifecycle rather than being a normal mutable variable.