Controlled vs uncontrolled inputs

I know there are a lot of articles regarding react forms. But, it doesn't hurt if I say something again in a very short explanation about react form input types. We all know that there two kinds of form inputs in react namely: controlled and uncontrolled inputs.

Controlled inputs

Controlled inputs accept their current value as a prop and a callback to change that value. That implies that the value of the input has to live in the React state somewhere. Typically, the component that renders the input (like a form component) saves that in its state:

const Form = () => { 
 const [value, setValue] = useState(""); 

 const handleChange = (e) => { 
   setValue(e.target.value) 
 } 

 return ( 
   <form> 
     <input 
       value={value} 
       onChange={handleChange} 
       type="text" 
     /> 
   </form> 
 ); 
};

Every time you type a new character, the handleChange function is executed. It receives the new value of the input, and then it sets it in the state. So, the Form component always has the input's current value without needing to ask for it explicitly.

As a result, your data (React state) and UI (input tags) are always in sync. Another implication is that forms can respond to input changes immediately, for example, by:

  • Instant validation per field

  • Disabling the submit button unless all fields have valid data

  • Enforcing a specific input format, like phone or credit card numbers

Sometimes you will find yourself not needing any of that. In that case uncontrolled could be a more straightforward choice.

Uncontrolled inputs

Unlike the controlled inputs where data is handled by the react component, in uncontrolled component, data is handled by the DOM itself. So, if we don't have controlled over its state, how do we access its value? To access the value of an uncontrolled input, we use the React Ref hook. For example, in the code below we use, the Ref hook to access the current value of the input

const Form = () => { 
 const inputRef = useRef(null); 

 const handleSubmit = () => { 
   const inputValue = inputRef.current.value; 
   // Do something with the value 
 } 
 return ( 
   <form onSubmit={handleSubmit}> 
     <input ref={inputRef} type="text" /> 
   </form> 
 ); 
};

Let me wrap up my little article, by mentioning that there are some specific form inputs that are always uncontrolled, like the file input tag.

In React, an is always an uncontrolled component because its value is read-only and can't be set programmatically.

const Form = () => { 
 const fileInput = useRef(null); 

 const handleSubmit = (e) => { 
   e.preventDefault(); 
   const files = fileInput.current.files; 
   // Do something with the files here 
 } 

 return ( 
   <form onSubmit={handleSubmit}> 
     <input 
       ref={fileInput} 
       type="file" 
     /> 
   </form> 
 ); 
};

React recommends using controlled inputs over uncontrolled inputs, but let me summarise in the table below.

controlled vs uncontrolled inputs

References: React docsReact forms by Gosha

0
Subscribe to my newsletter

Read articles from Brhane G. Ashebr directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Brhane G. Ashebr
Brhane G. Ashebr

๐Ÿ‘จโ€๐Ÿ’ป IT Professional | Security Research Analyst | Vulnerability Analyst ๐Ÿ”’ Passionate about enhancing the security of PHP-based applications, including WordPress, Drupal, and Joomla. ๐Ÿš€ 6+ years of experience in security research, patch development, and vulnerability analysis for open-source projects. ๐Ÿ›ก๏ธ Advocate for open-source security, performing meticulous code reviews and thorough testing to ensure stability and reliability. โ˜๏ธ AWS Certified Solutions Architect with hands-on experience designing and deploying scalable, secure cloud solutions. ๐Ÿ” Former SOC Analyst, specializing in monitoring, threat detection, and incident response. ๐Ÿค– Intermediate experience in LLM fine-tuning and AI agent development, leveraging AI for innovative solutions in security and automation. ๐ŸŽฏ Currently building a monetizable portfolio and side projects that bridge cutting-edge security practices, AI, and real-world solutions. ๐Ÿ’ก On a mission to empower developers, businesses, and website owners with secure, reliable, and AI-driven applications.