c2ce1066f2545c9fe4.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="4fca">For a controlled component, it doesn’t need to change the event handler, and neither does it need to prevent default behavior for the input element.</p>
<figure id="0efb">
<div>
<div>
<iframe class="gist-iframe" src="/gist/BetterProgramming/8482cd1528cb071f4945a547a24e9387.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><h1 id="5738">Example 5: Form Submission Use Case</h1><p id="d40d">Here is a form submission use case:</p><ul><li>There are two input fields: name and email. Name is a required field, and email needs to pass a regular expression test.</li><li>The first error is displayed in red if there is a validation error.</li><li>The submit button is enabled only when all input values are valid.</li><li>Immediately after submitting the form, the sent info is shown. This message stays until a user starts entering new values.</li></ul><p id="d970">The following code uses an uncontrolled component. The uncontrolled-specific lines are highlighted, where <code>handleChange</code> performs the validation and enables/disables the button.</p><div id="21ee"><pre><span class="hljs-keyword">const</span> <span class="hljs-title function_">App</span> = (<span class="hljs-params"></span>) => {
<iframe class="gist-iframe" src="/gist/BetterProgramming/4b65a7271c896ba32a3be773a20359c0.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="85d2">The same behavior can be coded in the controlled way. The following <code>App</code> is a controlled component, that manages data for <code>ShowUpperCase</code>. <code>ShowUpperCase </code>is also a controlled component.</p>
<figure id="2507">
<div>
<div>
<iframe class="gist-iframe" src="/gist/BetterProgramming/a6c2c2a887d9d948ce96dd6b020a5686.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><h1 id="9dd0">Conclusion</h1><p id="4948">You have seen a few examples of controlled and uncontrolled components. Either way works. You can choose a way to code your use cases.</p><p id="f51c">However, stick to one way for a specific component. Do not mix controlled and uncontrolled ways for the same component. Also, do not switch the type during the component’s lifetime.</p><p id="7456">Occasionally, you may encounter this warning in the debugger console:</p><div id="09bf"><pre>A component <span class="hljs-keyword">is</span> changing an uncontrolled <span class="hljs-keyword">input</span> <span class="hljs-keyword">of</span> <span class="hljs-keyword">type</span> checkbox <span class="hljs-keyword">to</span> be controlled. <span class="hljs-keyword">Input</span> elements should <span class="hljs-keyword">not</span> switch <span class="hljs-keyword">from</span> uncontrolled <span class="hljs-keyword">to</span> controlled (<span class="hljs-keyword">or</span> vice versa).</pre></div><p id="eb68">This may be caused by you unexpectedly setting the state to <code>null</code> or <code>undefined</code>, which is considered uncontrolled in React. When you unset a value, remember to set it to <code>‘’</code> or <code>false</code>.</p><p id="a098">Now it’s time to test your knowledge!</p><p id="6b05">In the following code, is <code>App</code> a controlled or uncontrolled component?</p>
<figure id="d69a">
<div>
<div>
<iframe class="gist-iframe" src="/gist/BetterProgramming/8f469b3b93c356c64c58f45524d4ba48.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="07e0">The answer is uncontrolled.</p><p id="818b">The <code>App</code> is written as a controlled component, but the <code>undefined</code> value switches the input element to be uncontrolled!</p><p id="5fc9">Thanks for reading. I hope this was helpful. If you have any questions, feel free to leave a response.</p></article></body>
To Be or Not to Be
Choosing between controlled and uncontrolled components in React
Controlled and uncontrolled components are two important concepts in React. It is vital to understand the difference between them and which cases best suit them.
What are controlled and uncontrolled components in React?
A controlled component manages its children’s data.
An uncontrolled component lets its children manage their own data.
The children mentioned in the above definition are typically HTML form elements, such as <input>, <textarea>, <select>, etc. In this article, we are going to use <input type=”text”> as example.
The children can also be React components.
Uncontrolled components use the natural HTML way, letting the DOM hold and update their values. The following App is an uncontrolled component, where the input value is maintained by the HTML element, <input>.
Controlled components are called the React way, recommended by the React team.
A controlled input accepts its value via a prop, and provides a callback to update this value. This value is typically held by the component’s state. The usage is straightforward.
Let’s use some examples to see the difference between controlled and uncontrolled components.
Example 1: Convert Each Input Keystroke to Uppercase
How do we manage an uncontrolled component? React provides event handlers to detect a change and then uses a callback to respond to the change.
In the below case, the onChange handler converts the uncontrolled input value to the uppercase. This happens on each keystroke.
This can be accomplished by using a controlled component as follows:
Example 2: Convert Each Input Keystroke to Uppercase With an Initial Value
We modify example one a bit to have an initial value. Here is how an uncontrolled component handles an initial value.
Here is how a controlled component handles an initial value:
Example 3: Convert Input to Uppercase After Clicking a Button
In this example, we want to demonstrate how the input element is managed by an outside event. The uppercase conversion is delayed until a button is clicked.
We face a problem. From the button’s event handler, we are not able to access this uncontrolled input field.
React provides refs to resolve this kind of problem. A ref is a way to access a DOM element or a React element.
In the following code, React.useRef() generates a ref, textInput. This ref is passed into the input element, and causes textInput.current to point to this input element when it is mounted.
Then, we are able to use textInput.current to manage this uncontrolled input value.
Here is the matching controlled component example:
Example 4: Convert Valid Input to Uppercase
We add validation to this example. Here, only letters are valid input. When an invalid key is typed, it is ignored and a red error message is displayed.
For an uncontrolled component, the generic onChange event handler is replaced by onKeyPress, since we may need to stop the default behavior before onChange happens.
For a controlled component, it doesn’t need to change the event handler, and neither does it need to prevent default behavior for the input element.
Example 5: Form Submission Use Case
Here is a form submission use case:
There are two input fields: name and email. Name is a required field, and email needs to pass a regular expression test.
The first error is displayed in red if there is a validation error.
The submit button is enabled only when all input values are valid.
Immediately after submitting the form, the sent info is shown. This message stays until a user starts entering new values.
The following code uses an uncontrolled component. The uncontrolled-specific lines are highlighted, where handleChange performs the validation and enables/disables the button.
Here is the equivalent controlled component code. The controlled-specific lines are highlighted, where handleChange updates children’s data and React.useEffect performs the validation and enables/disables the button.
We have mentioned in the beginning that the method identifying controlled and uncontrolled components can be applied to React component’s children.
In the following example, App is an uncontrolled component, although its child,ShowUpperCase, is a controlled component.
The same behavior can be coded in the controlled way. The following App is a controlled component, that manages data for ShowUpperCase. ShowUpperCase is also a controlled component.
Conclusion
You have seen a few examples of controlled and uncontrolled components. Either way works. You can choose a way to code your use cases.
However, stick to one way for a specific component. Do not mix controlled and uncontrolled ways for the same component. Also, do not switch the type during the component’s lifetime.
Occasionally, you may encounter this warning in the debugger console:
A component is changing an uncontrolled inputoftype checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).
This may be caused by you unexpectedly setting the state to null or undefined, which is considered uncontrolled in React. When you unset a value, remember to set it to ‘’ or false.
Now it’s time to test your knowledge!
In the following code, is App a controlled or uncontrolled component?
The answer is uncontrolled.
The App is written as a controlled component, but the undefined value switches the input element to be uncontrolled!
Thanks for reading. I hope this was helpful. If you have any questions, feel free to leave a response.