Conditional Form Fields Rendering

Loading

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, and Controller is used to wrap form fields.
  • watch is used to keep track of the value of the plan 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' and isAgreed).

Key Takeaways:

  1. React State: Use useState to track user selections and conditionally render form fields based on the state.
  2. Formik: The Field component in Formik allows you to conditionally render fields based on the form values, which is helpful for dynamic forms.
  3. React Hook Form: With useForm and Controller, React Hook Form also supports conditional rendering based on form state changes.

Leave a Reply

Your email address will not be published. Required fields are marked *