useState
The useState hook adds a piece of state to a function component. It takes an initialState and returns the current state paired with a setState function that updates it and re-renders the component.
Definition
useState is the React hook that gives a function component a piece of state — a value it remembers between renders. You call it at the top level of your component with an initial value, and it returns the current state and a function to change it. Calling that function updates the stored value and schedules a re-render, which is how the component's output stays in sync with its data.
It is the most fundamental of the React hooks and the one every interactive component is built on. For the concept behind it and when to reach for state at all, see React state — the basics. For running side effects after a render, its companion is the useEffect hook.
Syntax
import { useState } from 'react';
const [state, setState] = useState(initialState);
Parameters
| Parameter | Description |
|---|---|
initialState | The value the state starts at. It is used only on the first render and ignored on every render after that. It can be any type — a number, string, boolean, array or object. |
initialState as a function | If the initial value is expensive to compute, pass a function: useState(() => compute()). React calls it once, on the first render only. This is the lazy-initializer form of the same initialState argument. |
There is exactly one argument, initialState. Pass the value directly for a simple default, or pass a function when computing that default is costly and you want it to run just once.
Return value
useState returns an array of exactly two elements, which you destructure into a [state, setState] pair:
state— the current value for this render. On the first render it equalsinitialState; afterwards it is whatever you last set.setState— the setter function. Call it with the next value to store it and schedule a re-render:setState(nextValue). It does not changestatefor the render that is already running; the new value appears on the next render.- Updater-function form — when the next value depends on the previous one, call the setter with a function:
setState((prev) => prev + 1). React passes the latest value in asprevand stores what you return, which stays correct even when multiple updates are batched in one event.
The setter keeps a stable identity across renders, and React skips the re-render if you set a value equal to the current one (compared with Object.is). State updates are treated as immutable: pass a new value rather than mutating the existing one, or React may not detect the change.
Examples
A counter — read state, set the next value
The canonical example. useState(0) starts the count at zero; clicking calls setCount with the next number, which re-renders the button with the updated label.
The updater-function form
When several updates depend on the previous value, the updater form keeps them correct. Passing (c) => c + 1 three times adds three; passing count + 1 three times would only add one, because all three would read the same stale count.
State that is not a number
// initialState can be any type
const [name, setName] = useState(''); // string
const [open, setOpen] = useState(false); // boolean
const [user, setUser] = useState({ id: 1 }); // object
Browser & runtime support
useState has been part of React since hooks landed in React 16.8 and works in every modern React version, including React 18 and 19. It must be called at the top level of a component or of a custom hook — never inside a loop, condition or nested function — so React can match each state value to the right call across renders. That rule is the Rules of Hooks, and React's development build warns when it is broken.
Frequently asked questions
What does useState return?
const [state, setState] = useState(initial). The setter updates the value and re-renders the component.What is the initialState argument?
When should I use the updater-function form of setState?
setState((prev) => prev + 1) reads the latest value each time, avoiding stale updates.Why does my state update not appear immediately?
useState on that next render, not on the line right after you call the setter.