Conditional rendering of form fields allows you to display or hide certain form elements based on the user’s input or application logic. This is commonly required in forms where the fields change depending on the selections or choices made by the user, like showing additional fields based on a checkbox selection, radio button choice, or drop-down value.
In this guide, we will explore how to conditionally render form fields in React using different techniques, including standard React state and popular libraries like Formik and React Hook Form.
1. Conditional Rendering Using React State
In a simple form, we can conditionally render fields using React’s useState
hook to manage the form state and determine when a field should be displayed.
Basic Example: Showing Fields Based on a Checkbox
import React, { useState } from 'react';
const ConditionalForm = () => {
const [showExtraField, setShowExtraField] = useState(false);
const handleCheckboxChange = (event) => {
setShowExtraField(event.target.checked);
};
const handleSubmit = (event) => {
event.preventDefault();
// Handle form submission
console.log("Form submitted");
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
<input
type="checkbox"
checked={showExtraField}
onChange={handleCheckboxChange}
/>
Show extra field
</label>
</div>
<div>
<label htmlFor="name">Name:</label>
<input type="text" id="name" name="name" required />
</div>
{/* Conditionally rendered field */}
{showExtraField && (
<div>
<label htmlFor="extra">Extra Field:</label>
<input type="text" id="extra" name="extra" />
</div>
)}
<button type="submit">Submit</button>
</form>
);
};
export default ConditionalForm;
Explanation:
- The checkbox determines if the extra input field should be displayed or not.
- The state
showExtraField
is used to track whether the checkbox is checked. If it is checked, the extra field is rendered. - When the checkbox is unchecked, the field is hidden.
2. Conditional Rendering with Formik
Formik makes it easy to handle conditional rendering of form fields along with state and validation. Here’s how you can use Formik for dynamic fields based on user selection.
Example: Conditional Fields in Formik
import React from 'react';
import { Formik, Field, Form } from 'formik';
const ConditionalFormikForm = () => {
return (
<Formik
initialValues={{ subscription: 'basic', extraInfo: '' }}
onSubmit={(values) => {
console.log('Form submitted with values:', values);
}}
>
{({ values }) => (
<Form>
<div>
<label>Subscription Plan:</label>
<Field as="select" name="subscription">
<option value="basic">Basic</option>
<option value="premium">Premium</option>
</Field>
</div>
{/* Conditionally render the extra information field */}
{values.subscription === 'premium' && (
<div>
<label htmlFor="extraInfo">Extra Information:</label>
<Field type="text" name="extraInfo" id="extraInfo" />
</div>
)}
<button type="submit">Submit</button>
</Form>
)}
</Formik>
);
};
export default ConditionalFormikForm;
Explanation:
- Formik uses the
Field
component to handle form elements. Here, the subscription plan is a dropdown (<select>
), and the extra information field is conditionally rendered if the user selects the “premium” option. - Based on the value of
values.subscription
, the form will render the extra input field if the user selects “premium.”
3. Conditional Rendering with React Hook Form
React Hook Form also provides a flexible way to manage conditional fields using the useForm
hook. Here’s how to render fields conditionally based on user input.
Example: Conditional Fields with React Hook Form
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
const ConditionalRHFForm = () => {
const { control, handleSubmit, watch } = useForm({
defaultValues: {
plan: 'basic',
extraInfo: '',
},
});
const plan = watch('plan'); // Watch the plan field to conditionally render other fields
const onSubmit = (data) => {
console.log('Form submitted with data:', data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="plan">Subscription Plan:</label>
<Controller
name="plan"
control={control}
render={({ field }) => (
<select {...field} id="plan">
<option value="basic">Basic</option>
<option value="premium">Premium</option>
</select>
)}
/>
</div>
{/* Conditionally render the extra information field */}
{plan === 'premium' && (
<div>
<label htmlFor="extraInfo">Extra Information:</label>
<Controller
name="extraInfo"
control={control}
render={({ field }) => <input {...field} id="extraInfo" />}
/>
</div>
)}
<button type="submit">Submit</button>
</form>
);
};
export default ConditionalRHFForm;
Explanation:
useForm
from React Hook Form is used to manage form state, andController
is used to wrap form fields.watch
is used to keep track of the value of theplan
field, and based on this value, the “extra information” field is conditionally rendered.
4. Complex Conditional Form Fields
In more complex scenarios, you might need to show or hide fields based on multiple conditions or values from various form inputs. You can combine several conditions using logical operators.
Example: Multiple Conditions for Rendering Fields
import React, { useState } from 'react';
const ComplexConditionalForm = () => {
const [plan, setPlan] = useState('basic');
const [isAgreed, setIsAgreed] = useState(false);
const handlePlanChange = (event) => {
setPlan(event.target.value);
};
const handleAgreementChange = (event) => {
setIsAgreed(event.target.checked);
};
return (
<form>
<div>
<label>Subscription Plan:</label>
<select value={plan} onChange={handlePlanChange}>
<option value="basic">Basic</option>
<option value="premium">Premium</option>
</select>
</div>
<div>
<label>
<input
type="checkbox"
checked={isAgreed}
onChange={handleAgreementChange}
/>
Agree to terms and conditions
</label>
</div>
{/* Conditional fields */}
{plan === 'premium' && isAgreed && (
<div>
<label htmlFor="extra">Extra Field for Premium Users:</label>
<input type="text" id="extra" name="extra" />
</div>
)}
<button type="submit">Submit</button>
</form>
);
};
export default ComplexConditionalForm;
Explanation:
- This example has two conditions: the selected subscription plan (
plan
) and whether the user agrees to terms (isAgreed
). - The extra field is only shown if both conditions are satisfied (
plan === 'premium'
andisAgreed
).
Key Takeaways:
- React State: Use
useState
to track user selections and conditionally render form fields based on the state. - Formik: The
Field
component in Formik allows you to conditionally render fields based on the form values, which is helpful for dynamic forms. - React Hook Form: With
useForm
andController
, React Hook Form also supports conditional rendering based on form state changes.