Rare is the application that doesn’t rely on forms to get data from users, but how well do you really understand forms in React? What are your options? Did you know you had options? When should you use one over another?
Whether you’re starting out in React or you’re more experienced but swimming in a sea of code complexity, this post will help you level up your form prowess.
What are my options for getting form data?
You have more than one option! We’ll talk about these three options:
- Controlled inputs + onChange handlers
- Uncontrolled inputs + refs
- Uncontrolled inputs + form serialization
All three examples log the final values of the inputs to the console on submit so that you can compare the options.
Controlled inputs + onChange handlers
If you’ve dallied in React forms at all, chances are you are aware of controlled inputs. Facebook focuses on this method of capturing your form data in the official docs.
The idea is that you give the input a starting
state as well as an
onChange method. The
onChange method updates the
state which in turn re-renders the input with the new value. When a user submits the form, all the final values are eagerly awaiting your next move in the
state. Here is a basic example:
Uncontrolled inputs + refs
The React documentation also mentions uncontrolled inputs, but as a footnote. Why? I can’t answer that. We’ll talk about the pros and cons a little later. First, let’s look at how to get form data from uncontrolled inputs using refs.
You can put a
ref attribute on any component, and you supply it with a callback function. The callback function’s input is the underlying DOM element itself. Thus, it allows us to access the current
value of the HTML
<input />, and then set a property on the component class with that value. On submit, we just need to grab all those class properties to send the data to the console:
Facebook considers refs as “escape hatches” and discourages using them when you could use a more declarative solution. Don’t hijack the normal data flow in React unless you have to.
Uncontrolled inputs + form serialization
Note that for uncontrolled inputs, you can set an initial value for the input using the
defaultValue attribute. This works for both the ref and serialization methods.
The million dollar question — which should I use?
The most important question you need to answer is:
When do you need to access your form data?
In other words, do you need access to the data before submitting or is after submit adequate? If you had a controlled form, would the
onChange method do anything other than update the value of the input field in state?
If you only need your data after submit, then uncontrolled inputs using either method are simpler and less tedious. They also don’t re-render on every single character change of the inputs, though this excess rendering isn’t a performance problem for most forms. You can still validate data and re-render the form with errors. You can also easily clear errors on focus.
In terms of which uncontrolled inputs method to use, I prefer serialization. For longer forms, it gives me a tidy little package with all my form data without having to access each ref individually. For me, it’s more intuitive, but play with both and see which you prefer.
If you need your data before submit, then controlled inputs are your solution. They can perform live validation and conditional disabling of submit buttons. Live validations validate the inputs while the user types rather than on submit. In some cases, this is helpful — like for password strength hints.
Now go forth on the high seas of forms, confident in how to navigate through the waves of options! (too cheesy?)
— — —
Want to go back to basics on forms? Check out George Mauer’s article HTML Forms’ Time Has Come (Again).
Would you like an article on adding validations to forms? Or how to think through encapsulating form state? Let me know!
If you liked this story, give it a💚 to share the love.