I'm practicing React (with Hooks) where I'm trying to create a simple sign up form (with Hooks) which takes 3 input fields: Name, Email and Password.
For some reason, the controlled component input fields are not updating or allowing the user to enter any values.
Original Practice Sign-Up Form: (NOT working)
Sandbox: https://codesandbox.io/s/green-wave-plfszp?file=/src/components/SignUpForm.js
Code Block:
import React, { useState } from "react";
export default function SignUpForm() {
const [userState, setUserState] = useState({
name: "",
email: "",
password: ""
});
const [submitted, setSubmitted] = useState(false);
const handleFormSubmit = (event) => {
event.preventDefault();
setSubmitted(true);
};
const handleInputChange = (event) => {
const { name, value } = event.target;
setUserState((prevProps) => ({
...prevProps,
[name]: value
}));
};
return submitted ? (
<>
<p>
Successfully registered <br />
Name: {userState.name} <br />
Email: {userState.email}
</p>
</>
) : (
<>
<h1>Sign-up</h1>
<form onSubmit={handleFormSubmit}>
<label name={userState.name} htmlFor={userState.name}>
Name:
</label>
<br />
<input
type="text"
name={userState.name}
value={userState.name}
onChange={handleInputChange}
/>
<br />
<label name={userState.email} htmlFor={userState.email}>
Email:
</label>
<br />
<input
type="text"
name={userState.email}
value={userState.email}
onChange={handleInputChange}
/>
<br />
<label name={userState.password} htmlFor={userState.password}>
Password:
</label>
<br />
<input
type="password"
name={userState.password}
value={userState.password}
onChange={handleInputChange}
/>
<br />
<button type="submit">Submit</button>
</form>
</>
);
}
I tried debugging this in various ways and found another standard login form, which I forked to create a similar version of my original practice sign-up form. This seems to be working perfectly fine.
Forked Standard Login Form: (working)
Sandbox: https://codesandbox.io/s/login-form-forked-lj6gmm?file=/src/App.js
Code Block:
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [state, setState] = useState({
email: "",
password: ""
});
const [submit, setSumbit] = useState(false);
const handleInputChange = (event) => {
const { name, value } = event.target;
setState((prevProps) => ({
...prevProps,
[name]: value
}));
};
const handleSubmit = (event) => {
event.preventDefault();
setSumbit(true);
console.log(state);
};
return submit ? (
<div className="App">
Successfully registered <br />
Email: {state.email} <br />
Password: {state.password}
</div>
) : (
<div className="App">
<form onSubmit={handleSubmit}>
<div className="form-control">
<label>Email</label>
<input
type="text"
name="email"
value={state.email}
onChange={handleInputChange}
/>
</div>
<div className="form-control">
<label>Password</label>
<input
type="password"
name="password"
value={state.password}
onChange={handleInputChange}
/>
</div>
<div className="form-control">
<label></label>
<button type="submit">Login</button>
</div>
</form>
</div>
);
}
What is the issue in the original practice sign-up form that I created? I'm curious why its working in a certain file only.
CodePudding user response:
your issue here is that you try to extract the name from event. if you would try to log the name you extracted it would be empty:
const handleInputChange = (event) => {
const { name, value } = event.target;
console.log(name)
setState((prevProps) => ({
...prevProps,
[name]: value
}));
};
what you can do is pass the prop name on change.
const handleInputChange = (event, propName) => {
const { value } = event.target;
setUserState((prevProps) => ({
...prevProps,
[propName]: value
}));
};
and on your form.
<br />
<input
type="text"
name={userState.name}
value={userState.name}
onChange={(e) => handleInputChange(e, "name")}
/>
<br />
<label name={userState.email} htmlFor={userState.email}>
Email:
</label>
<br />
<input
type="text"
name={userState.email}
value={userState.email}
onChange={(e) => handleInputChange(e, "email")}
/>
<br />
<label name={userState.password} htmlFor={userState.password}>
Password:
</label>
<br />
<input
type="password"
name={userState.password}
value={userState.password}
onChange={(e) => handleInputChange(e, "password")}
/>
<br />
CodePudding user response:
You just need change the name of your input from this:
<input
type="text"
name={userState.name}
value={userState.name}
onChange={handleInputChange}
/>
to this:
<input
type="text"
name="name"
value={userState.name}
onChange={handleInputChange}
/>
Note: Just need change the attribute name
of your input.