Conditional Fields
Show, hide, or require fields based on another field's value - and keep form validity correct as they appear and disappear.
Forms often change shape based on what the user picks: a "Business" account reveals a company name, a
"Other" option reveals a free-text box. With gform-react you do this with plain React - read a field's
value and conditionally render the dependent GInputs.
The important part is what happens to validity: a GInput registers when it mounts and unregisters
when it unmounts. So a hidden field's value leaves form state and stops counting toward
isValid/isInvalid - a conditionally-hidden required field won't block submit while it's not
showing. (Same lifecycle that powers Dynamic Fields.)
Reading a value to decide what renders
Take the function child to access state, read the controlling field's value, and branch:
<GForm<AccountForm> validators={validators} onSubmit={handleSubmit}>
{(state) => (
<>
<GInput
formKey="accountType"
value="personal"
element={(input, props) => (
<select {...props}>
<option value="personal">Personal</option>
<option value="business">Business</option>
</select>
)}
/>
{/* Only mounted - and only required - when "business" is selected */}
{state.accountType?.value === "business" && (
<GInput
formKey="companyName"
required
element={(input, props) => (
<label>
<span>Company name</span>
<input {...props} />
{input.error && <small>{input.errorText}</small>}
</label>
)}
/>
)}
<button disabled={state.isInvalid}>Continue</button>
</>
)}
</GForm>When the user switches back to "Personal", companyName unmounts: its value drops out of
toRawData() and the form is valid again without it.
Because hidden fields unregister, toggling one off and on again starts it fresh (re-seeded from
its value prop, if any). That's usually what you want for conditional fields. If you need to keep
a hidden field's value, render it always and hide it with CSS (hidden / display: none) instead of
unmounting it - it stays registered and keeps contributing to validity.
Reading from a deep child with useFormSelector
If the controlling field and the conditional field live in different components, you don't need the
render prop - subscribe to just the value you care about with
useFormSelector:
import { useFormSelector } from "gform-react";
function CompanyFields() {
const accountType = useFormSelector((state) => state.fields.accountType?.value);
if (accountType !== "business") return null;
return <GInput formKey="companyName" required element={/* … */} />;
}It re-renders only when accountType changes, so the rest of the form stays untouched. See
Nested Forms for more.
Try it live
Switch to Business and the company fields appear (and companyName becomes required); tick the
newsletter box and a frequency field appears. The toRawData() readout shows only the fields that are
currently mounted.
See Dynamic Fields for adding/removing repeated fields and Dispatching Changes for setting values programmatically.