Search code examples
reactjsformsuser-inputonchange

Why is my input field not editable even after adding onChange function - react


I am a new learner in react, I tried a simple login form which takes user input and passes it to backend. This application is also written to create tokens if the login credentials are correct. In order to take user input I have added the onChange() function and called it for each input field, however the it is still not editable. I couldn't find the error. I also have added onSubmit() function implementation. I did try various other ways of calling the onChange function, however it wasnt successful.

 const [formData, setFormData] = useState({
        clientEmail: "",
        clientPassword: "",
        errorMsg: false,
        loadingSpinner: false,
      });
      
      // destructure form data
      const { clientEmail, clientPassword, errorMsg, loadingSpinner } = formData;
    const handleChange = (evt) => {
          setFormData({
            ...formData,
            [evt.target.name]: evt.target.value,
            errorMsg: "",
          });
        };
    
const handleSubmit = (evt) => {
      evt.preventDefault();
    
      //form validation
      if (isEmpty(clientEmail) || isEmpty(clientPassword)) {
        setFormData({
          ...formData,
          errorMsg: "All field are Required",
        });
      } else if (!isEmail(clientEmail)) {
        setFormData({
          ...formData,
          errorMsg: "Invalid Email new",
        });
      } else {
        const { clientEmail, clientPassword} = formData;
      
        const data = {
          clientEmail,
          clientPassword,
        };
        setFormData({
          ...formData,
          loadingSpinner: true,
        });
       
        ClientLoginUser(data)
          .then((response) => {
     
            console.log(response);
            setClientAuthentication(response.data.token, response.data.clients);
          
          
              if (isClientAuthenticated()) {  
            console.log("client Successful");
              history.push("./clientDashboard");
            }
          })
          .catch((err) => {
            console.log("client login api controller error: ", err);
            setFormData({
              ...formData,
              errorMsg:err.response.data.errorMessage,
              loading:false
            });

          });
      }
    };
    
    const showLoginForm = () => (
        <Fragment>
          <div className="card px-5 py-5">
           
            <div className="card-body">
              <h5 className="card-title text-center pb-3">Client Login</h5>
              <form className="login-form" 
              onSubmit={handleSubmit} 
              noValidate>
    
                {/* Email */}
                <div className="form-group">
                  <input
                    type="email"
                    className="form-control"
                    name="email"
                     value={clientEmail}
                    placeholder="Email"
                     onChange={handleChange}
                  />
                </div>
                {/* Password */}
                <div className="form-group">
                  <input
                    type="password"
                    className="form-control"
                    name="password"
                     value={clientPassword}
                    placeholder="Password"
                    onChange={handleChange}
                  />
                </div>
                {/* Submit button */}
                <div className="form-group pt-3">
                  <button
                    type="submit"
                    className="btn btn-primary btn-lg btn-block"
                  >
                    Login
                  </button>
                </div>
              </form>
            </div>
          </div>
        </Fragment>
      );
    
      /****************************
       * Render
       ****************************/
      return (
        <div className="login-container">
          <GridWrapper>
            <div className="container-fluid">
              <div className="row px-4 vh-100">
                <div className="col-12 col-md-8 my-auto pl-5">
                  <img
                    src="/images/welcomeLogo.png"
                    className="img-fluid"
                    alt="Logo"
                  />
                </div>
                <div className="col-12 col-md-3 align-self-center">
                  {errorMsg && showErrorMsg(errorMsg)}
                  {loadingSpinner && (
                    <div className="text-center pb-5">{showLoading()}</div>
                  )}
    
                  {showLoginForm()}
                </div>
              </div>
            </div>
          </GridWrapper>
        </div>
      );
    };
      // return <p>ClientLogin Component</p>;

Solution

  • The name in input is not exactly the same as in formData state

    you got this state

    const [formData, setFormData] = useState({
        clientEmail: "",
        clientPassword: "",
        errorMsg: false,
        loadingSpinner: false,
      });
    

    which contain data like clientEmail

    <input
        type="email"
        className="form-control"
        name="email"
        value={clientEmail}
        placeholder="Email"
        onChange={handleChange}
      />
    

    which contains name="email"

    in handleChange Function

    const handleChange = (evt) => {
          setFormData({
            ...formData,
            [evt.target.name]: evt.target.value,
            errorMsg: "",
          });
        };
    

    you contains [evt.target.name]: evt.target.value

    thats mean you are trying to assign new Values to formData.email not to formData.clientEmail

    there are two solution

    first you can change

    const [formData, setFormData] = useState({
        email: "",
        ...
      });
    

    or you can

    <input
     type="email"
      className="form-control"
      name="clientEmail"
      value={clientEmail}
      placeholder="Email"
      onChange={handleChange}
    />