React Forms
React Forms
Section titled “React Forms”Formkove works with any React setup. Here’s a simple approach using useState and fetch.
Simple Component
Section titled “Simple Component”import { useState } from "react";
export default function ContactForm() { const [status, setStatus] = useState(""); const [result, setResult] = useState("");
const handleSubmit = async (e) => { e.preventDefault(); setStatus("Sending...");
const formData = new FormData(e.target);
const data = Object.fromEntries(formData.entries());
try { const res = await fetch("https://app.formkove.com/api/forms/YOUR_FORM_ID/submissions", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify(data) });
const json = await res.json();
if (res.ok) { setStatus("Message sent!"); setResult(""); e.target.reset(); } else { setStatus("Error"); setResult(json.error || "Something went wrong."); } } catch (err) { setStatus("Error"); setResult("Network error. Please try again."); } };
return ( <form onSubmit={handleSubmit}> <input type="text" name="name" placeholder="Your name" required /> <input type="email" name="email" placeholder="Email address" required /> <textarea name="message" placeholder="Your message" required /> <button type="submit" disabled={status === "Sending..."}> {status || "Send"} </button> {result && <p>{result}</p>} </form> );}With react-hook-form
Section titled “With react-hook-form”If you prefer react-hook-form for validation and state management:
import { useState } from "react";import { useForm } from "react-hook-form";
export default function ContactForm() { const { register, handleSubmit, reset, formState: { errors, isSubmitting, isSubmitSuccessful } } = useForm({ mode: "onTouched" });
const [message, setMessage] = useState("");
const onSubmit = async (data) => { setMessage("Sending...");
try { const res = await fetch("https://app.formkove.com/api/forms/YOUR_FORM_ID/submissions", { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify(data) });
const json = await res.json();
if (res.ok) { setMessage("Sent! We'll be in touch."); reset(); } else { setMessage(json.error || "Something went wrong."); } } catch (err) { setMessage("Network error. Check your connection."); } };
return ( <form onSubmit={handleSubmit(onSubmit)}> <div> <input type="text" placeholder="Full name" {...register("name", { required: "Name is required" })} /> {errors.name && <span>{errors.name.message}</span>} </div>
<div> <input type="email" placeholder="Email address" {...register("email", { required: "Email is required", pattern: { value: /^\S+@\S+$/, message: "Invalid email" } })} /> {errors.email && <span>{errors.email.message}</span>} </div>
<div> <textarea placeholder="Message" {...register("message", { required: "Message is required" })} /> {errors.message && <span>{errors.message.message}</span>} </div>
<button type="submit" disabled={isSubmitting}> {isSubmitting ? "Sending..." : "Send Message"} </button>
{message && <p>{message}</p>} </form> );}Key Points
Section titled “Key Points”- Form ID goes in the URL, not as a hidden field in React
- Use
Content-Type: application/jsonfor fetch submissions - Handle both success (200) and error responses
form.reset()clears the form after success