How to Get All Form Values on Submit in React
To get all form values upon form submission in React, we need to attach an onChange
event handler to our input fields and store their values in a state object using a setState
hook. Take a look at the following example:
import { useState } from 'react'
export default function App() {
const [data, setData] = useState({})
const updateData = e => {
setData({
...data,
[e.target.name]: e.target.value
})
}
const submit = e => {
e.preventDefault()
console.log(data)
}
return (
<form onSubmit={submit}>
<input
name="email"
type="email"
onChange={updateData}
/>
<input
name="password"
type="password"
onChange={updateData}
/>
<button>Submit</button>
</form>
)
}
We have one useState
hook that will store all form values. This is updated with an onChange
handler on the inputs that sets the object to the existing values plus sets a key dynamically on line 9 based on the name
of the input field.
Make sure you call e.preventDefault
in your submit
function to prevent a page refresh on form submit.
This will return the data in an object where the key corresponds to the name of the input and the value to its value. The value of the data
state will be the following in this case:
This approach makes it very flexible to scale your forms, as you only need to attach the onChange
handler on new inputs and the form values will be added automatically to your state.
Using useState
A more verbose approach is to use useState
for individual fields. In this approach, we create a useState
for each individual field and use an onChange
event handler on them to set the value to the current target. In terms of code, this is how it changes our component:
import { useState } from 'react'
export default function App() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const submit = e => {
e.preventDefault()
console.log(email, password)
}
return (
<form onSubmit={submit}>
<input
name="email"
type="email"
onChange={event => setEmail(event.target.value)}
value={email}
/>
<input
name="password"
type="password"
value={password}
onChange={event => setPassword(event.target.value)}
/>
<button>Submit</button>
</form>
)
}
We can grab the useState
fields inside the submit
function one by one. Note that this requires us to manually set up a new useState
for each new field, and also update the appropriate field in the onChange
handler.
Using Refs
We could also use refs by using the useRef
hook. This approach is very similar to using useState
, but instead of setting the state to a value, we grab the DOM element instead, and we can get the value from the DOM node.
import { useRef } from 'react'
export default function App() {
const email = useRef()
const password = useRef()
const submit = e => {
e.preventDefault()
console.log(email.current.value, password.current.value)
}
return (
<form onSubmit={submit}>
<input
name="email"
type="email"
ref={email}
/>
<input
name="password"
type="password"
ref={password}
/>
<button>Submit</button>
</form>
)
}
Again, this approach is less flexible than the very first example, as we need to add a new ref for each field. However, there is no need for an onChange
handler as we can store the correct reference using the custom ref
prop on the input fields. This approach creates an uncontrolled component, as now the state handling is detached from React, and instead, handled by the DOM.
Note that in order to grab the correct value, we'll need to reference current.value
, instead of the ref itself.
Using event.target
Lastly, we can use event.target
on the form itself. This approach is probably the simplest among all, as we don't need to use any hooks. However, with this approach, we don't have access to all form values outside of the function, unless we build a state object inside the function, and pass it to a variable that is defined outside of it.
export default function App() {
const submit = e => {
e.preventDefault()
console.log(e.target.email.value, e.target.password.value)
}
return (
<form onSubmit={submit}>
<input
name="email"
type="email"
/>
<input
name="password"
type="password"
/>
<button>Submit</button>
</form>
)
}
Also, the way we can grab the input values a bit differently. We'll be able to access all of them under event.target[name].value
, where the name
property references the name
attribute of the input.
Rocket Launch Your Career
Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies: