The wrong question most teams ask first
Teams often ask whether a form is big enough to deserve useReducer. That is not the best first question. A form can have many fields and still work cleanly with useState if the fields mostly change independently.
The real question is whether the state transitions form one coherent model. If updates must stay consistent across validation, async submission, dirty tracking, and recovery paths, a reducer often creates a clearer contract.
When useState is still the better choice
useState wins when the component is mostly local, the fields do not trigger complex coupled transitions, and the update logic is easy to read inline. In those cases a reducer can add ceremony without adding clarity.
- Choose useState when fields are mostly independent and validation is lightweight.
- Prefer derived values over extra state when totals, errors, or completion flags can be computed during render.
- Do not move to a reducer just because the component grew a few more inputs.
When a reducer starts paying for itself
A reducer becomes valuable when one user action needs to change several related pieces of state together. Submission, reset, async recovery, and server validation are common examples.
The reducer is not magic. Its value is that it exposes the transition model in one place, which makes code review and test design easier than following state updates across many setters.
A practical migration rule
Do not migrate because the file feels crowded. Migrate when the next bug you expect is a transition bug rather than an individual field bug.
If the likely failure is that pending, error, success, and field data can drift apart, a reducer is probably the right simplification. If not, keep the lighter tool.