useState Hook
useState Hook — React state basics
In React, state represents data that, when changed, causes React to re-render the component with
new values.
If you use a regular variable, React won't know that the value has changed and won't update the DOM.
React provides a special Hook called useState that allows you to create and manage state inside a component.
The syntax is as follows:
const [state, setState] = useState(initialValue);
Let's create the most basic example — a counter that increments with each click.
import React, { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(prev => prev + 1)}>Increment</button>
</div>
);
}
In this example:
0setCount function changes the count value.
If you change the state multiple times in a row, React might batch these updates and use the old value.
Therefore, it's correct to use the callback version: setCount(prev => prev + 1).
function increaseTwice() {
// ❌ Incorrect way
setCount(count + 1);
setCount(count + 1);
// ✅ Correct way
setCount(prev => prev + 1);
setCount(prev => prev + 1);
}
If the state is an object, you must change it in an immutable way — without mutating the original object. Use the spread (...) operator.
import React, { useState } from 'react';
export default function Profile() {
const [profile, setProfile] = useState({
name: 'Aram',
age: 30,
location: 'Yerevan'
});
function updateName() {
setProfile(prev => ({ ...prev, name: 'Mikhael' }));
}
return (
<div>
<p>Name: {profile.name}</p>
<p>Age: {profile.age}</p>
<p>City: {profile.location}</p>
<button onClick={updateName}>Change Name</button>
</div>
);
}
Common mistake: directly mutating the state like profile.name = '...' — this won't cause a re-render.
In React, array state must also be updated immutably. Don't use push(); instead, create a new array.
const [tasks, setTasks] = useState(['Write article', 'Read React docs']);
function addTask() {
// ❌ Incorrect way — mutates the same array
// tasks.push('New task');
// setTasks(tasks);
// ✅ Correct way
setTasks(prev => [...prev, 'New task']);
}
As a result, React will understand that the state has changed and will update the UI.
If the initial value needs to be calculated by an expensive operation, use the functional version:
const [value, setValue] = useState(() => {
const saved = localStorage.getItem('value');
return saved ? JSON.parse(saved) : 0;
});
This version is calculated only once — during the initial render.
Write a component that:
Try to apply the callback setter and immutable update approaches.