Home > Software design >  setting the value of more than one input
setting the value of more than one input

Time:12-12

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);
}
  • Related