Uncontrolled components in React are form elements that maintain their own internal state. Instead of using React state to track input values, uncontrolled components rely on refs to directly access the DOM element values when needed. This approach is similar to traditional HTML form handling.
This form demonstrates uncontrolled components using refs to access input values directly from the DOM.
// UncontrolledForm.tsx
import React, { useRef } from "react";
interface UncontrolledFormProps {
onSubmit: (formData: {
name: string;
email: string;
message: string;
}) => void;
}
export const UncontrolledForm: React.FC<UncontrolledFormProps> = ({ onSubmit }) => {
// Create refs for form elements
const nameRef = useRef<HTMLInputElement>(null);
const emailRef = useRef<HTMLInputElement>(null);
const messageRef = useRef<HTMLTextAreaElement>(null);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Access current DOM values directly using refs
if (nameRef.current && emailRef.current && messageRef.current) {
const formData = {
name: nameRef.current.value,
email: emailRef.current.value,
message: messageRef.current.value,
};
onSubmit(formData);
}
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="name" className="block mb-1 text-sm font-medium">
Name
</label>
<input
type="text"
id="name"
ref={nameRef}
defaultValue=""
className="w-full p-2 border rounded focus:ring focus:ring-blue-200"
required
/>
</div>
<div>
<label htmlFor="email" className="block mb-1 text-sm font-medium">
Email
</label>
<input
type="email"
id="email"
ref={emailRef}
defaultValue=""
className="w-full p-2 border rounded focus:ring focus:ring-blue-200"
required
/>
</div>
<div>
<label htmlFor="message" className="block mb-1 text-sm font-medium">
Message
</label>
<textarea
id="message"
ref={messageRef}
defaultValue=""
rows={4}
className="w-full p-2 border rounded focus:ring focus:ring-blue-200"
required
/>
</div>
<button
type="submit"
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Submit
</button>
</form>
);
};