← Back to Recipes

React Form Example

A complete React component that posts submissions to your Peach Form endpoint.

1. Copy the Component

No new dependencies required — uses built-in React hooks and the browser Fetch API.

// ContactForm.jsx
import { useState } from "react";

const ENDPOINT = "https://api.peachform.com/f/YOUR_FORM_ID";

export function ContactForm() {
  const [fields, setFields] = useState({
    name: "",
    email: "",
    message: "",
  });
  const [status, setStatus] = useState("idle"); // idle | loading | success | error

  function handleChange(e) {
    setFields((prev) => ({ ...prev, [e.target.name]: e.target.value }));
  }

  async function handleSubmit(e) {
    e.preventDefault();
    setStatus("loading");

    try {
      const res = await fetch(ENDPOINT, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(fields),
      });
      setStatus(res.ok ? "success" : "error");
    } catch {
      setStatus("error");
    }
  }

  if (status === "success") {
    return <p>Thanks! Your message was received.</p>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        name="name"
        value={fields.name}
        onChange={handleChange}
        placeholder="Name"
        required
      />
      <input
        name="email"
        type="email"
        value={fields.email}
        onChange={handleChange}
        placeholder="Email"
        required
      />
      <textarea
        name="message"
        value={fields.message}
        onChange={handleChange}
        placeholder="Message"
        required
      />
      <button type="submit" disabled={status === "loading"}>
        {status === "loading" ? "Sending..." : "Send"}
      </button>
      {status === "error" && (
        <p>Something went wrong. Please try again.</p>
      )}
    </form>
  );
}

2. Replace YOUR_FORM_ID

Copy your form endpoint from the Peach Form dashboard and replace YOUR_FORM_ID in the ENDPOINT constant.

3. Render the Component

// App.jsx
import { ContactForm } from "./ContactForm";

export default function App() {
  return (
    <main>
      <h1>Contact Us</h1>
      <ContactForm />
    </main>
  );
}

Expected Behavior

// Idle:    form fields visible, submit button enabled
// Loading: button shows "Sending..." and is disabled
// Success: form replaced with "Thanks! Your message was received."
// Error:   "Something went wrong. Please try again." shown below button