Dependent Fields
When one field’s options or validity depend on another (e.g. country → city), keep them in sync and reset the dependent field when the parent changes.
The problem I keep seeing
Forms often have cascading choices: country then city, product then variant, plan then add-ons. The dependent field’s options (and value) must come from the parent. If the user changes the parent, the dependent value can become invalid and should be reset and re-validated.
Naive approach
Two independent fields; city options are static or ignore country. When the user picks a country, the city list doesn’t update and the current city might be invalid for the new country.
First improvement
Derive the dependent options from the parent value (e.g. a map or async fetch). When the parent changes, reset the dependent field and optionally disable it until the parent is set. This keeps options and value in sync.
Remaining issues
- Validation: Submit-time validation must treat the dependent field as conditional (e.g. required only when parent has a value, or must be in the derived list).
- Async options: If the dependent options come from an API (e.g. cities for country), show loading for the second field and clear it when the parent changes.
- Form libraries: With React Hook Form (or similar), use
watchfor the parent andsetValue+clearErrorswhen the parent changes.
Production pattern
Use watch on the parent field. In a useEffect (or when handling the parent’s change), call setValue(dependentField, '') and clearErrors(dependentField). Derive options (from a map or query) based on the watched parent. In your schema (e.g. Zod), use refine or superRefine so the dependent field is validated in context (e.g. “city required when country is set” and “city must be in list for that country”).
When I use this
- Country / region / city: Classic cascade; reset city when country changes.
- Product → variant, plan → add-ons: Options and price depend on the first choice.
- Skip when: The second field’s options never change based on the first; treat as two independent fields.
Gotchas
- Reset on parent change: Always clear (or reset) the dependent value when the parent changes; otherwise you can submit “UK” + “New York”.
- Async list: While loading cities for the new country, disable the city dropdown or show a “Loading…” option so the user doesn’t pick a stale value.
- Schema: Client and server validation should both enforce “city in allowed list for country”; don’t rely only on the client-derived options.