I am trying to build a login form. I am trying to set up the value of the email & password field individually. But as soon as I try to enter the text in the email text field, the same appears in the password field too. Can I have a solution to this?
Below is the code.
I guess the error is in OnChange
fn where I am assigning the same value e.target.value
to both the {email, passwaord}.
import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
const LoginPage = () => {
let navigate = useNavigate();
const [credentials, setCredentials] = useState({email:"",password:""});
const onChange = (e) => {
setCredentials({email: e.target.value ,password: e.target.value})
console.log(credentials.email, credentials.password)
}
const goToSignUp = () => {
navigate("/signup");
}
return (
<>
<div className="container my-5">
<div id="loginbody">
<div className="mt-3">
<h2 className="my-3 display-3">Login Here</h2>
<form className="login-form p-5">
<div className="mb-3">
<label for="exampleInputEmail1" className="form-label">
Email address
</label>
<input
type="email"
className="form-control"
id="email"
name="email"
value={credentials.email}
aria-describedby="emailHelp"
onChange={onChange}
/>
<div id="emailHelp" className="form-text">
We'll never share your email with anyone else.
</div>
</div>
<div className="mb-3">
<label for="exampleInputPassword1" className="form-label">
Password
</label>
<input
type="password"
className="form-control"
id="password"
name="password"
value={credentials.password}
onChange={onChange}
/>
</div>
<div className="d-grid gap-2 my-4 col-6 mx-auto">
<button type="submit" className="btn btn-success">
Submit
</button>
</div>
<hr />
<div className="mb-3 text-center">
<div id="emailHelp" className="form-text center my-3">
Didn't have an account ?
</div>
<div className="d-grid gap-2 my-3 col-6 mx-auto">
<button onClick={goToSignUp} className="btn btn-success ">
SignUp Here !
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</>
);
};
export default LoginPage;
CodePudding user response:
You have identified the problem. You need to pass the key to change as well.
Here passing a callback to setState
which provides the current state as a parameter, cloning the state object using spread syntax, and then updating the relevant property in the copied object using the passed key as a computed property name.
const LoginPage = () => {
const [credentials, setCredentials] = useState({email:"",password:""});
const onChange = (e, key) => {
setCredentials(prevCredentials => ({...prevCredentials, [key]: e.target.value}))
}
return (
<>
//...
<input
type="email"
className="form-control"
id="email"
name="email"
value={credentials.email}
aria-describedby="emailHelp"
onChange={(e) => onChange(e, 'email')}
/>
//...
<input
type="password"
className="form-control"
id="password"
name="password"
value={credentials.password}
onChange={(e) => onChange(e, 'password')}
/>
//...
</>
);
};
Note: Calling console.log()
right after setting state will not log the updated state, the new state values won't be available until the next render cycle. see: useState set method not reflecting change immediately
CodePudding user response:
Use the proper key to the respective fields
const onChange = (e) => {
setCredentials({ ...credentials, [e.target.name]: [e.target.value]})
console.log(credentials);
}