useState
Declares a state variable that triggers re-renders when updated. The most fundamental React hook for managing component-level state.
Signature
const [state, setState] = useState<T>(initialState: T | (() => T))Parameters
| Parameter | Type | Description |
|---|---|---|
| initialState | T | () => T | The initial value for the state variable, or a lazy initializer function that returns the initial value. |
Return Value
A tuple of [state, setState]. state is the current value. setState is a function that accepts a new value or an updater function (prev => next) and schedules a re-render.
Examples
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(prev => prev - 1)}>Decrement</button>
</div>
);
}import { useState } from 'react';
function UserForm() {
const [user, setUser] = useState({ name: '', email: '' });
const updateField = (field: string, value: string) => {
setUser(prev => ({ ...prev, [field]: value }));
};
return (
<form>
<input
value={user.name}
onChange={e => updateField('name', e.target.value)}
placeholder="Name"
/>
<input
value={user.email}
onChange={e => updateField('email', e.target.value)}
placeholder="Email"
/>
</form>
);
}import { useState } from 'react';
function ExpensiveComponent() {
// The initializer function only runs on the first render
const [data, setData] = useState(() => {
const saved = localStorage.getItem('app-data');
return saved ? JSON.parse(saved) : { items: [], filter: 'all' };
});
const addItem = (item: string) => {
setData(prev => ({
...prev,
items: [...prev.items, item],
}));
};
return <div>{data.items.length} items loaded</div>;
}Common Pitfalls
Mutating state directly instead of creating a new reference — always spread objects/arrays to create new copies.
Calling setState in a loop without using the updater function form, which can lead to stale closures.
Using an expensive computation as initialState without wrapping it in a function — pass () => expensiveCompute() instead.
Expecting state updates to be synchronous — React batches updates and the new value is only available on the next render.
Understanding useState
useState is the cornerstone of React's hook-based state management. Introduced in React 16.8, it allows function components to hold and update local state without converting to class components. When you call useState, React allocates a slot in the component's fiber node to persist the value across re-renders.
The setter function returned by useState can accept either a direct value or an updater function. The updater form (prev => next) is essential when the new state depends on the previous state, especially inside event handlers or effects where closures might capture stale values. React batches multiple setState calls within the same event handler into a single re-render for performance.
State updates in React are immutable by convention. For objects and arrays, you must create new references for React to detect changes. Directly mutating an object property and passing the same reference to setState will not trigger a re-render. This immutability pattern is what enables React's efficient reconciliation algorithm.
Lazy initialization is an important optimization. If your initial state requires an expensive computation — such as parsing localStorage, filtering a large dataset, or running a complex calculation — wrap it in a function. React will only call this initializer on the first render, skipping it entirely on subsequent re-renders. This can significantly improve mount performance for components that initialize with heavy data processing.
Related Hooks
useReducerManages complex state logic with a reducer function. Preferred over useState when state transitions depend on the previous state or involve multiple sub-values.
useRefCreates a mutable ref object that persists across renders without triggering re-renders when its value changes. Commonly used for DOM access and storing mutable instance variables.
useContextReads and subscribes to a context value. Re-renders the component whenever the nearest provider's value changes.
More State Management Hooks
Explore All React Hooks
Browse our complete reference of 19 React hooks with signatures, examples, pitfalls, and in-depth explanations.