Clean β’ Professional
When working with forms in React, you have two main approaches for managing form data:

Choosing the right approach depends on your app complexity, validation needs, and interaction patterns.
Example β Controlled Input
value={name}).onChange handler.import React, { useState } from "react";
function ControlledForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
alert(`Submitted Name: ${name}`);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={name} onChange={handleChange} />
<button type="submit">Submit</button>
</form>
);
}
export default ControlledForm;
An uncontrolled form is one where the DOM manages the input state.
React doesnβt directly control the value; instead, you access it using refs.
Example β Uncontrolled Input
useRef accesses the current value when needed.import React, { useRef } from "react";
function UncontrolledForm() {
const nameRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
alert(`Submitted Name: ${nameRef.current.value}`);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={nameRef} />
<button type="submit">Submit</button>
</form>
);
}
export default UncontrolledForm;
| Feature | Controlled Components | Uncontrolled Components |
|---|---|---|
| Data Flow | React state controls input | DOM handles input |
| Value | value prop tied to state | Accessed via ref |
| Validation | Easy and real-time | Manual, after submission |
| Updates | State updates trigger re-render | DOM manages updates |
| Recommended Use Case | Complex forms, dynamic updates | Simple forms, quick prototypes |
| Event Handling | onChange required | onSubmit only, optional onChange |
You can also combine controlled and uncontrolled components in large forms, managing critical inputs via state while letting other inputs remain uncontrolled for simplicity.
Example β Controlled vs Uncontrolled
import React, { useState, useRef } from "react";
function FormComparison() {
const [controlledName, setControlledName] = useState("");
const uncontrolledNameRef = useRef();
const handleSubmit = () => {
alert(
`Controlled: ${controlledName}, Uncontrolled: ${uncontrolledNameRef.current.value}`
);
};
return (
<div>
<inputtype="text"
value={controlledName}
onChange={(e) => setControlledName(e.target.value)}
placeholder="Controlled"
/>
<input type="text" ref={uncontrolledNameRef} placeholder="Uncontrolled" />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
export default FormComparison;Β