Back to cookbook

ChatGPT Prompt to Build a Reusable React Form Component with Validation

Updated
Share

This ChatGPT prompt generates a reusable React form component with built-in field validation, meant for frontend developers who want a working starting point instead of wiring up form state and error handling from scratch each time. It's suited for common cases like signup forms, contact forms, or settings panels.

The prompt specifies the fields, validation rules, and styling approach up front so the model produces a self-contained component with local state management, inline error messages, and a disabled submit state while the form is invalid — rather than a form that only looks right but skips validation logic entirely.

It's written for React with plain useState, since that runs without extra dependencies, but the constraints section lets you swap in a form library like React Hook Form or Formik, or specify TypeScript, if that matches your codebase.

Prompt template

Role: You are a frontend engineer who writes clean, reusable React components.

Context:
- Component purpose: [E.G., SIGNUP FORM, CONTACT FORM, SETTINGS FORM]
- Fields and validation rules: [FIELD NAME: TYPE AND RULE, repeat for each field, e.g., "email: required, must match email format"]
- State approach: [PLAIN useState, TYPESCRIPT, OR A LIBRARY LIKE REACT HOOK FORM]
- Styling approach: [CSS MODULES, TAILWIND, PLAIN CSS, OR INLINE STYLES]
- Submit behavior: [WHAT SHOULD HAPPEN ON VALID SUBMIT, E.G., "CALL AN onSubmit PROP WITH FORM VALUES"]

Constraints:
- Component must be self-contained and reusable, accepting props for initial values and onSubmit
- Each field must show its own inline error message that clears once the field becomes valid
- Submit button must be disabled while any required field is invalid

Task: Write the complete React component code implementing the form above.

Output format:
1. The full component code in a single fenced code block
2. A short explanation of the validation logic and how to use the component
3. Any assumptions made about props or styling

Example input

Component purpose: Newsletter signup form
Fields and validation rules: name: required, minimum 2 characters; email: required, must match a standard email format
State approach: plain useState, JavaScript (no TypeScript)
Styling approach: plain CSS with a "form-field" and "form-error" class
Submit behavior: call an onSubmit prop with { name, email } when the form is valid

Example output

1. Component code:
```jsx
import { useState } from "react";

function validate(values) {
  const errors = {};
  if (!values.name || values.name.trim().length < 2) {
    errors.name = "Name must be at least 2 characters.";
  }
  const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!values.email || !emailPattern.test(values.email)) {
    errors.email = "Enter a valid email address.";
  }
  return errors;
}

export default function NewsletterSignupForm({ onSubmit }) {
  const [values, setValues] = useState({ name: "", email: "" });
  const [errors, setErrors] = useState({});

  const handleChange = (e) => {
    const { name, value } = e.target;
    const nextValues = { ...values, [name]: value };
    setValues(nextValues);
    setErrors(validate(nextValues));
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const validationErrors = validate(values);
    setErrors(validationErrors);
    if (Object.keys(validationErrors).length === 0) {
      onSubmit(values);
    }
  };

  const isValid = Object.keys(validate(values)).length === 0;

  return (
    <form onSubmit={handleSubmit}>
      <div className="form-field">
        <label htmlFor="name">Name</label>
        <input id="name" name="name" value={values.name} onChange={handleChange} />
        {errors.name && <span className="form-error">{errors.name}</span>}
      </div>
      <div className="form-field">
        <label htmlFor="email">Email</label>
        <input id="email" name="email" value={values.email} onChange={handleChange} />
        {errors.email && <span className="form-error">{errors.email}</span>}
      </div>
      <button type="submit" disabled={!isValid}>Subscribe</button>
    </form>
  );
}
```

2. Explanation:
The `validate` function checks both fields and returns an errors object. Validation runs on every keystroke and again on submit, and the submit button is disabled whenever `validate` returns any errors. Pass an `onSubmit` prop to receive `{ name, email }` once the form is valid.

3. Assumptions:
Assumed plain CSS classes `form-field` and `form-error` are defined elsewhere in the project, and that no initial values need to be pre-filled.

When to use it

  • Scaffolding a new signup, login, or contact form for a React project
  • Adding client-side validation to a form that currently submits without checks
  • Prototyping a settings or profile-edit form before wiring it to a real API
  • Generating a starting component to adapt to your team's existing form library

Best practices

  • List every field with its exact validation rule instead of saying "validate the form"
  • Specify whether you're using plain React state, TypeScript, or a form library like Formik
  • Ask for inline error messages tied to each field, not just a generic form-level error
  • Request that the submit button stay disabled until all required fields pass validation

Common mistakes

  • Not specifying validation rules, which produces a form with only required-field checks
  • Leaving out the styling approach, so the model guesses between CSS modules, Tailwind, or inline styles
  • Accepting the first draft without checking that error messages clear once a field is fixed
  • Asking for "a form" instead of specifying controlled vs. uncontrolled inputs, which affects how state is wired

FAQs

How do I get ChatGPT to generate React form validation, not just the UI?

List each field's exact validation rule in the prompt (required, format, min length) instead of a general instruction to "validate the form," so the model writes real validation logic.

Can this prompt generate a TypeScript version instead?

Yes, change the state approach line to specify TypeScript and the model will add prop and state types, though you should still review the generated types against your project's conventions.

Should I use this for a form library like Formik or React Hook Form instead of plain useState?

Specify the library in the state approach section and the model will use its API instead of plain useState; plain state is simplest when you don't want an extra dependency.

Why does the submit button start disabled?

The prompt requires the button to stay disabled until every required field passes validation, which prevents submitting incomplete or invalid data by mistake.

Found this prompt useful? Share it.

Share