Home > Back-end >  How to check if an input is empty to apply a specific class?
How to check if an input is empty to apply a specific class?

Time:11-23

I am new on react. I am creating a view "login", I have two fields in the form, email and password. I need to check when these inputs are empty to apply a specific icon class, and if they are not empty apply another actived class.

<span className={emailIsEmpty ? "icon" : "icon actived"}>

This class is simply to change the color of the icons when the user is entering data into the inputs. enter image description here

I Create a "useEffect" for each field.

If the element changes, it will check if the input is empty and will return a boolean indicating the current state.

// Email Field
useEffect(() => {
  if (email === "") {
    emailIsEmpty = true;
  } else {
    emailIsEmpty = false;
  }
}, [email]);

but I am unable to perform this functionality

Line 33:25: Assignments to the 'passwordIsEmpty' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect

Line 24:22: Assignments to the 'emailIsEmpty' variable from inside React Hook useEffect will be lost after each render. To preserve the value over time, store it in a useRef Hook and keep the mutable value in the '.current' property. Otherwise, you can move this variable directly inside useEffect

LoginView.js

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";

const LoginView = function () {

  let emailIsEmpty,
    passwordIsEmpty = null;

  const [formState, setFormState] = useState({
    email: "",
    password: "",
  });

  const { email, password } = formState;

  const handleInputChange = function (e) {
    setFormState({
      ...formState,
      [e.target.name]: e.target.value,
    });
  };

// Email Field
useEffect(() => {
  if (email === "") {
    emailIsEmpty = true;
  } else {
    emailIsEmpty = false;
  }
}, [email]);

  // Password Field
  useEffect(() => {
    if (password === "") {
      passwordIsEmpty = true;
    } else {
      passwordIsEmpty = false;
    }
  }, [password]);

  return (
    <div className="container">
      <div className="card-login">
        <div className="card-img">
          <img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
          <h1>Login</h1>
        </div>
        <form>
          <div className="form-input">
            <span className={emailIsEmpty ? "icon" : "icon actived"}>
              <i class="fas fa-envelope-open-text"></i>
            </span>
            <input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
          </div>
          <div>
            <div className="form-input">
              <span className={passwordIsEmpty ? "icon" : "icon actived"}>
                <i class="fas fa-key"></i>
              </span>
              <input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
            </div>
          </div>
          <div>
            <button className="button response">Login</button>
          </div>

          <div className="forget-password">
            <Link to="/">Forgot password?</Link>
          </div>
        </form>
      </div>
    </div>
  );
};

export default LoginView;

CodePudding user response:

Remove UseEffect in your code for changing input value its not a better approach it will re render the component every time value change. this can be possible if you make you can simply apply check on your formState.email or formState password. Now in your onChnageHandler function.

 const handleInputChange = function (e) {
    setFormState({
      ...formState,
      [e.target.name]: e.target.value,
    });
//put your condition here
  if (formState.email=="")
  {
    setEmailisEmpty(true);
  }
  else{
     setEmailisEmpty(false);
  }
  };
 <form>
      <div className="form-input">
        <span className={emailIsEmpty ? "icon" : "icon actived"}>
          <i class="fas fa-envelope-open-text"></i>
        </span>
        <input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
      </div>
      <div>
        <div className="form-input">
          <span className={passwordIsEmpty ? "icon" : "icon actived"}>
            <i class="fas fa-key"></i>
          </span>
          <input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
        </div>
      </div>
      <div>
        <button className="button response">Login</button>
      </div>

      <div className="forget-password">
        <Link to="/">Forgot password?</Link>
      </div>
    </form>

CodePudding user response:

In my opinion, you don't need two flags(emailIsEmpty and passwordIsEmpty). Rather, you can use the state itself to add the class conditionally.

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";

const LoginView = function () {


const [formState, setFormState] = useState({
 email: "",
 password: "",
});



const handleInputChange = function (e) {
setFormState({
  ...formState,
  [e.target.name]: e.target.value,
});
};


return (
<div className="container">
  <div className="card-login">
    <div className="card-img">
      <img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
       <h1>Login</h1>
     </div>
    <form>
      <div className="form-input">
        <span className={!formState.email? "icon" : "icon actived"}>
          <i class="fas fa-envelope-open-text"></i>
        </span>
        <input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
      </div>
      <div>
        <div className="form-input">
          <span className={!formState.password ? "icon" : "icon actived"}>
            <i class="fas fa-key"></i>
          </span>
          <input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
        </div>
      </div>
      <div>
        <button className="button response">Login</button>
      </div>

      <div className="forget-password">
        <Link to="/">Forgot password?</Link>
      </div>
    </form>
  </div>
</div>
);
};

export default LoginView;

CodePudding user response:

You are updating a variable inside the useEffect function which will not work on render. Because react component only render based on state or props changes.

So You can check the constant variable before the return but not inside useEffect.

emailIsEmpty = email === "";
passwordIsEmpty = password === "";

return (
....

So your component should be look like-

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";

const LoginView = function () {

  let emailIsEmpty,
    passwordIsEmpty = null;

  const [formState, setFormState] = useState({
    email: "",
    password: "",
  });

  const { email, password } = formState;

  const handleInputChange = function (e) {
    setFormState({
      ...formState,
      [e.target.name]: e.target.value,
    });
  };

  emailIsEmpty = email === "";
  passwordIsEmpty = password === "";

  return (
    <div className="container">
      <div className="card-login">
        <div className="card-img">
          <img src="//ssl.gstatic.com/accounts/ui/avatar_2x.png" alt="profile-img" className="profile-img-card" />
          <h1>Login</h1>
        </div>
        <form>
          <div className="form-input">
            <span className={emailIsEmpty ? "icon" : "icon actived"}>
              <i class="fas fa-envelope-open-text"></i>
            </span>
            <input name="email" placeholder="Email address" type="email" onChange={handleInputChange} value={email} />
          </div>
          <div>
            <div className="form-input">
              <span className={passwordIsEmpty ? "icon" : "icon actived"}>
                <i class="fas fa-key"></i>
              </span>
              <input name="password" placeholder="Password" type="password" onChange={handleInputChange} value={password} />
            </div>
          </div>
          <div>
            <button className="button response">Login</button>
          </div>

          <div className="forget-password">
            <Link to="/">Forgot password?</Link>
          </div>
        </form>
      </div>
    </div>
  );
};

export default LoginView;


For the multiple classes, you can use a package called classnames for joining multiple classes together.

  • Related