React and ReactJS
Keep the current component and form fields. Send the values to SmartFormify, then use React state for loading, success, error, and redirect behavior.
Component flow
FormData
Fetch
State
The request stays in the component. A separate Express or serverless form route is optional.
Component setup
SmartFormify returns the JSON used by the component for success, errors, redirects, and thank-you content. Use the environment tab when deployments need different endpoint URLs.
React contact form
jsx
This form uses FormData and React state to handle the JSON returned by SmartFormify. The same request shape works with a controlled form.
import { useState } from "react";
const ENDPOINT_URL = "https://api.smartformify.com/fe/YOUR_ENDPOINT_KEY";
export default function ContactForm() {
const [status, setStatus] = useState("idle");
const [message, setMessage] = useState("");
async function handleSubmit(event) {
event.preventDefault();
const form = event.currentTarget;
if (!form.reportValidity()) return;
setStatus("loading");
setMessage("");
const data = Object.fromEntries(new FormData(form).entries());
try {
const response = await fetch(ENDPOINT_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ data })
});
const result = await response.json();
if (!response.ok || !result.success) {
throw new Error(result.message || "Submission failed.");
}
if (result.data.redirect_url) {
window.location.assign(result.data.redirect_url);
return;
}
setMessage(result.data.thank_you_content);
setStatus("success");
form.reset();
} catch (error) {
setMessage(error.message);
setStatus("error");
}
}
return (
<form onSubmit={handleSubmit}>
<label>
Email
<input type="email" name="email" required />
</label>
<label>
Message
<textarea name="message" required />
</label>
<button disabled={status === "loading"}>
{status === "loading" ? "Sending..." : "Send"}
</button>
{message && (
<div
role={status === "error" ? "alert" : "status"}
dangerouslySetInnerHTML={{ __html: message }}
/>
)}
</form>
);
}01
The form is ready and values can be edited.
02
Disable submit while the request is active.
03
Show confirmation or follow the redirect.
04
Keep values and display the returned message.
Uncontrolled form
Use this approach when React does not need every field value during typing. It keeps the submit handler short.
Controlled form
Use this approach when the component already stores values for conditional UI or custom validation. Send that object inside data.