Dynamic Fields and Form Libraries

Show Fields Based on Input

Example

Keep conditions out of messy JSX with a small wrapper component.

import { useState } from 'react';

function ShowIf({ when, children }) {
  return when ? children : null;
}

export default function App() {
  const [type, setType] = useState('individual');
  const [news, setNews] = useState(false);
  return (
    <form>
      <select value={type} onChange={(e) => setType(e.target.value)}>
        <option value="individual">Individual</option>
        <option value="business">Business</option>
      </select>
      <ShowIf when={type === 'business'}>
        <p><input placeholder="Company name" /></p>
      </ShowIf>
      <p><label><input type="checkbox" checked={news} onChange={(e) => setNews(e.target.checked)} /> Newsletter</label></p>
      <ShowIf when={news}>
        <input type="email" placeholder="Email for newsletter" />
      </ShowIf>
    </form>
  );
}

Result

React Hook Form

For big forms use a library such as React Hook Form (fast, uncontrolled) or Formik, often with Yup or Zod for validation schemas.

import { useForm } from 'react-hook-form';

function Signup() {
  const { register, handleSubmit, formState: { errors } } = useForm();
  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input {...register('email', { required: 'Email is required' })} />
      {errors.email && <p>{errors.email.message}</p>}
      <button>Submit</button>
    </form>
  );
}