How to get form data on submit in ReactJS
Let’s say you have a form, and you have handleSubmit()
function when a user clicks on the button.
How do you get the form data in that handleSubmit()
function?!
const handleSubmit = () => {
// ... get data form
// ... submit to API or something
}
const FooBarForm = () => {
return (
<>
<label>
Username
<input />
</label>
<br />
<label>
Password
<input />
</label>
<br />
<button onClick={handleSubmit}>Submit</button>
</>
);
}
Ideal solution: Use React setState or useState
You may use React class setState
method or the React hook useState
. In this example I will be using useState
.
First, above my functional component I will create a new variable object called, initialFormData
.
const initialFormData = Object.freeze({
username: "",
password: ""
});
Now I will update my functional component, FooBarForm
.
const FooBarForm = () => {
const [formData, updateFormData] = React.useState(initialFormData);
const handleChange = (e) => {
updateFormData({
...formData,
// Trimming any whitespace
[e.target.name]: e.target.value.trim()
});
};
const handleSubmit = (e) => {
e.preventDefault()
console.log(formData);
// ... submit to API or something
};
return (
<>
<label>
Username
<input name="username" onChange={handleChange} />
</label>
<br />
<label>
Password
<input name="password" onChange={handleChange} />
</label>
<br />
<button onClick={handleSubmit}>Submit</button>
</>
);
};
Let’s do a quick code breakdown.
The first chunk of code inside FooBarForm
is to initialize React useState
.
const [formData, updateFormData] = React.useState(initialFormData);
I’m providing initialFormData
as my initial state value. If you’re not familiar with React useState
, read up on it here.
The next snippet of code that’s important are my handler functions handleChange()
, and handleSubmit()
.
const handleChange = (e) => {
updateFormData({
...formData,
// Trimming any whitespace
[e.target.name]: e.target.value.trim()
});
};
const handleSubmit = (e) => {
e.preventDefault()
console.log(formData);
// ... submit to API or something
};
The first thing you should’ve notice is that I moved my handleSubmit()
function inside FooBarForm
functional component.
I did that so I can just access the formData
variable right away.
You can extract these functions out of the functional component, but will require you to write your functions to allow values to pass through an event handler function. You can read up on that over here.
The handleChange()
function is a critical piece. It’s responsible for updating my React state.
handleChange()
is going to grab the element’s name
value and map it to the formData
state object.
Since it’s a string value, I’m trimming any white spaces.
The next update to this form is just updating the <input>
elements.
<label>
Username
<input name="username" onChange={handleChange} />
</label>
<br />
<label>
Password
<input name="password" onChange={handleChange} />
</label>
<br />
<button onClick={handleSubmit}>Submit</button>
I’ve given each input field its own name
property. The value of each name matches the initialFormData
property.
So each input element is mapped to its own formData
property.
I’m also attaching my handleChange()
function to each input element onChange
event.
That’s it!
When you fill out the form, and click the submit button the console will display
Object {username: "your string value", password: "your string value"}
Now, I want to show you another method that works, but is NOT the ideal solution.
Not ideal solution: useRef
You might be tempted to use React useRef
because it’s easier to grab the element reference rather than doing all the useState
boilerplate code.
const FooBarForm = () => {
const usernameRef = React.useRef();
const passwordRef = React.useRef();
const handleSubmit = () => {
console.log(usernameRef.current.value, passwordRef.current.value);
};
return (
<>
<label>
Username
<input ref={usernameRef} />
</label>
<br />
<label>
Password
<input ref={passwordRef} />
</label>
<br />
<button onClick={handleSubmit}>Submit</button>
</>
);
};
React useRef
has its use-cases, but capturing form data is not one of them.
If you like to learn when to use React useRef
, check out this article piece here.
I like to tweet about React and post helpful code snippets. Follow me there if you would like some too!