If you'll go to the official React website it says that the recommended way to use inputs is to control them via React state. It also mentions that in some cases you can go with an uncontrolled option but do not say what are these cases explicitly. Let’s try to dive into it and see the pros and cons of this approach.
Controlled input values are being kept in the local state. Every time the user changes the content of the input, the
onChange function updates the React state, Component rerenders with the new value passed to Input.
On the other hand, uncontrolled inputs are being handled by the browser itself. So you don’t have direct control over inputs value in the component, but you can use ref to get access to it.
Looking at these two examples you can clearly say that the second one looks cleaner and less verbose than the first one. You don’t need to instantiate state, pass the value to each input and override
An uncontrolled form doesn’t have state, so every time you type, your component doesn’t re-render, increasing overall performance.
By leveraging uncontrolled inputs you’re trusting browser with form management and become closer to the native implementation. Why do you need to write something that was already created anyway? 🤔
Use refs. With new Hooks API, refs became a more stable and better way to control DOM. Consider the following example where you need to access forms values outside of the
Browser API provides you with a lot of useful features to handle forms and inputs.
form.reset()— use the reset function to clear all your fields
form.submit()— use it to programmatically submit the form
form.reportValidity()— checks validation constraints and returns
document.forms— interface that allows you to access all forms on the page.
Constraint Validation API — set of properties and methods that allows you to create complex validations on the fields.
required— all of that and much more is covered by it.
Basically you need to choose controlled inputs when you need to re-render your component on every type. For example, you want to display or send all form values as you type (imagine autocomplete field for the search bar). Or if you need to pass input value to child component through props. There are quite a few cases where you have to use it.
I believe that uncontrolled components are currently undervalued and should have more presence in modern React applications. Indeed they’re not gonna solve all your problems but would help increase the performance and reliability of your components in many cases.