State is data that changes over time — form inputs, toggled menus,
counters, fetched data. useState is the hook that makes it possible.
Basic state
JSX
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}useState(0) returns [count, setCount] — the current value and a
function to update it. When setCount is called, React re-renders the
component with the new value.
Updating objects
JSX
function Profile() {
const [user, setUser] = useState({ name: 'Ram', age: 22 });
const haveBirthday = () => {
// ❌ Don't mutate directly
// user.age++;
// ✅ Spread and override
setUser({ ...user, age: user.age + 1 });
};
return (
<div>
<p>{user.name}, age {user.age}</p>
<button onClick={haveBirthday}>Happy Birthday!</button>
</div>
);
}Updating arrays
JSX
function TodoList() {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState('');
const addTodo = () => {
if (!input.trim()) return;
setTodos([...todos, { id: Date.now(), text: input, done: false }]);
setInput('');
};
const toggleTodo = (id) => {
setTodos(todos.map(todo =>
todo.id === id ? { ...todo, done: !todo.done } : todo
));
};
return (
<div>
<input value={input} onChange={e => setInput(e.target.value)} />
<button onClick={addTodo}>Add</button>
{todos.map(todo => (
<div key={todo.id} onClick={() => toggleTodo(todo.id)}>
{todo.done ? '✅' : '⬜'} {todo.text}
</div>
))}
</div>
);
}Derived state
JSX
function Cart({ items }) {
// Don't store this as state — derive it!
const total = items.reduce((sum, item) => sum + item.price * item.qty, 0);
return <p>Total: NPR {total}</p>;
}If you can compute it from existing state or props, don't store it as separate state. This prevents bugs from forgetting to update derived values.
Tips
- Never mutate state directly — always use the setter function.
- State updates are asynchronous — React batches updates for performance.
- Derive what you can from state/props instead of storing redundant copies.
- Keep state as close to where it's used as possible.
Next: events.