The Complete Guide to Building React Forms with useState Hook
In this tutorial, You’ll learn how to build forms with one or more input fields using JSX, understand how an HTML uncontrolled form transforms to a React controlled state form, retrieve the form data when submitted and save it to state using useState hook and finally, pass form data as props to a component and have the component render the data on the browser.
The project we will be building is a Contact form with three input fields for the contact’s name, email, and phone number. when the form is submitted, the form data will be saved in a contacts state and passed to a contact list component, where it is rendered to the browser.
If you want a quick overview of how to build forms with multiple input fields using react hook, you can view it here. This article will beginner-focused or for anyone who wants to refresh their knowledge on building React forms with useState hook.
1. Build a simple React form with multiple input fields
npx create-react-app contact-info
Get rid of everything you don’t need, here’s a link to what my app looks like after getting rid of content and files I don’t need; Cleanup application
In the src folder, create a file src/components/ContactForm.jsx
, this component contains the code to build the form.
Adding the type
to the input field, HTML validates the email and number input. It will check that whatever the user inputs for email is an email and for phone number must be a number.
Import UserForm.jsx
into App.js
to see the form rendered on your browser.
2. Converting JSX Form to a Controlled Form with React Hooks
Now that we have a simple form being rendered on the browser, we are going to convert the form input state to be controlled by React. By default, forms handle their own state. Converting the form to a controlled state is telling React to take over the form state from the browser in the following ways;
- Creating a
state
object to store the form data. React usesuseState hook
to handle the form state. - Add the
value
property to the form, and assign it to thestate
object properties. - Add an
onChange event listener
function to handle updating the form state.
useState
is a React hook used to manage state in functional components.
state
is the information we don’t want to lose while the page re-renders.
Navigate to src/components/ContactForm.jsx
, import useState hook from React.
Create a contact
state with the form input names as the properties.
Add thevalue
property to each input field and set the value
to the contact
state properties as illustrated below.
React now has control over the form but we are yet to update the input fields.
we are setting value
in the input fields to the contact
state properties.
If you check your form in the browser, you will realise you can’t type in the input fields, that’s because React has no way to track the value of input elements.
The onChange event Listner
is how React updates the input fields in real-time.
Let’s add a handleChange
function to take care of updating the input fields. Add this below contact
state.
const handleChange = (event) => {setContactInfo({ ...contactInfo, [event.target.name]:event.target.value });};
setContactInfo
is a function that comes with useState Hook
and it’s used to update our current state object.
To preserve the previous state, we spread the contactInfo
data using the javascript spread operator. This way, the previous data is not lost while we update the input state.
For example, without spreading the previous state, the only state that will be saved in the contact
state when you submit the form data is phone number
. setContactInfo
will replace the old state with the new state which will be the last input field you updated( phone number ).
To handle multiple controlled input elements, setContactInfo
uses the name
attribute to update the contact
state properties based on the values from event.target.name
.
3. Retrieving Form Data from Controlled Input Field.
Now, Let’s log the form data to the console using a handlesubmit
function.
handleSubmit
function will log the contactInfo
state to the browser.
Navigate to ContactInfo
and add the handleSubmit
function.
Pass the handleSubmit
function to an onSubmit event listener
in the <form>
tag. When the submit button is clicked, the user data is logged to the console.
const handleSubmit = (event) => {// prevents the submit button from refreshing the pageevent.preventDefault();console.log(contactInfo);};
4. Display Form Data in Another Component
In this phase, you learn how to pass data from parent component to child component. Data will be passed from App.js
(parent) to the ContactList
(child) component where it is displayed.
Now that we have our form data, let’s display this data in ContactList.jsx
.
Before that, let’s create a contacts
state in App.js
to store each contactInfo
object retrieved from ContactForm.jsx
.
contacts
state will be passed as props to the ContactList.jsx
component.
Navigate to App.js and create a contacts
state using useState
React Hook and set it to an empty array.
Create an addContact
function that takes contactInfo
as a parameter for updating the contacts
state.
pass addContact
as props
to the ContactForm.jsx
component. This is also an example of passing data from parent to child component.
Using object destructuring in javascript, get addContact
from props, Update the handleSubmit
function so instead of logging the data to the console, pass it as a parameter to the addContact
function.
When you submit the form, the contacts
state is updated with the new form state.
Now that we have an array of contacts, let’s display each contact info in a ContactList
component.
Pass Contacts
state data as props to a React component.
Last on the agenda is setting up the ContactList.jsx
to display the contacts
state.
create a ContactList
file in src/components
and export a simple <div>
tag to prevent the app from breaking.
Import ContactList
file into App.js and pass contacts
data as props to contactList
component.
Navigate to src/ContactList.jsx
, retrieve the props data passed into the component using destructing as we did for ContactForm.jsx
.
Due to contacts
data being an array, we need a way to display each contact
detail. I’m using Array.prototype.map() to loop through each value in and set the key attribute value to phone number because it is guaranteed to be unique. The key attribute is how React keeps track of the values in the array.
the `<p>`
tag is used to display name
, email
and phone number
of each contact object
At this point, when you fill the form and click on the submit button, the data is displayed on the page.
Conclusion
In this tutorial, I covered;
- how to set up a basic React app using create-react-app and create a simple jsx form.
- how React converts an uncontrolled form to a controlled form component.
- how to retrieve the form data and pass it as props to another component.
- Create a React functional component that takes the form data as props and renders it to the browser.
To view the full project code, link to Github repository.