Async Actions
A guide to handling async component interactions with React actions.
Use action props when a component interaction performs async work. Regular callback props are still the right tool for synchronous updates, observation, analytics, and canceling a change. When the callback saves data, submits a mutation, or waits for server-derived state, prefer an action prop.
Base UI provides action props for async interaction points:
ButtonusesclickActionfor async clicks.SelectusesvalueChangeActionfor async value changes.
The action is run in a React transition. Select also applies the next value optimistically while the action is pending, so the interface reflects the user’s intent immediately.
Why use actions?
Actions make async interactions part of React’s update model instead of a separate side effect that each component has to coordinate manually.
When you use an action with useActionState, React owns the pending state for the async operation:
Then pass the dispatcher to the component action prop:
This keeps the committed value, pending state, and optimistic UI path aligned with the same async transaction.
Why not manage the state yourself?
You can build the same behavior with regular callback props, but you have to reimplement the async state machine in userland.
Examples
Select menu
For example, this Select waits to update its controlled value until the request finishes:
The visible selection stays on the old value while the request is pending, which makes the interaction feel frozen.
To make the regular callback version feel as responsive as an action, you need to manage:
- The committed value from the server.
- A separate optimistic value for the displayed selection.
- Pending state for the in-flight request.
- Stale request cancellation when the user chooses another value.
- Rollback behavior when the request fails or is canceled.
- Server-normalized values when the response differs from the requested value.
That usually turns into a custom state machine:
With an action, React owns the pending state and Base UI keeps the selected value optimistic while the action is pending:
Actions do not make this behavior impossible with regular callbacks. They make the responsive version the default shape instead of requiring every component consumer to write this coordination code.
When to use regular callbacks
Use regular callback props when the work is synchronous:
Also use regular callbacks for observation and cancellation:
Use action props when the interaction itself performs async work:
React owns the pending state, and Button guards against duplicate activations while the returned promise is pending.
Canceling stale work
React actions are queued. If the user can make several async changes quickly, use an AbortController in the action payload to cancel stale requests:
Canceling stale work keeps the latest interaction from waiting behind obsolete requests.