Consider this example (CodeSandbox):
import { useState } from "react";
export default () => {
const [email, setEmail] = useState("");
return (
<form method="post" action="/example">
<input type="text" name="first-name" />
<input type="text" name="last-name" />
<input
type="email"
value={email}
onChange={(e) => {
setEmail(e.target.value);
}}
/>
<button type="submit">submit</button>
</form>
);
};
If you type in "foo" for the first name, "bar" for the last name, and "[email protected]" for the email, the payload that is submitted to the server is first-name=foo&last-name=bar
, not first-name=foo&last-name=bar&[email protected]
. This is because email is a controlled component whereas the other two are uncontrolled.
The most obvious thing to do would be to refactor the form to use all controlled components, but I’m looking for a way that would be easier and less time consuming.
2
Answers
One option would be to hijack the
onSubmit
event like this (CodeSandbox):At a high level, the idea is to:
FormData
that otherwise would have been sent to the server.FormData
.It's not quite plug-n-play, but at least you don't have to spend the time making the existing uncontrolled components controlled. (1) is probably the most cumbersome, but it doesn't seem too bad.
Looks like I just forgot the
name
attribute!With the above, the payload that is submitted to the server is like so, as expected: