React icon button showing warning message after click

i have used FaEye, FaEyeSlash react icons as you can see in the below login code but every time i click on them i get the following warning message,i want that not to happen.note that i was using tailwindcss, but to fix this problem i tried using normal css.

bundle.js:17688 Warning: Invalid values for props $typeof, type on tag. Either remove them from the element, or pass a string or number value to keep them in the DOM. For details, see https://reactjs.org/link/attribute-behavior at svg at IconBase at span at div at div at div at form at Login (http://localhost:3000/static/js/bundle.js:3883:76) at RenderedRoute (http://localhost:3000/static/js/bundle.js:278126:5) at Routes (http://localhost:3000/static/js/bundle.js:278563:5) at Routing at App (http://localhost:3000/static/js/bundle.js:349:78) at Router (http://localhost:3000/static/js/bundle.js:278501:15) at BrowserRouter (http://localhost:3000/static/js/bundle.js:276818:5)

Login.jsx

import { useContext, useState } from "react";
import { Link, Navigate } from "react-router-dom";
import axios from "axios";
import { FaEye, FaEyeSlash } from "react-icons/fa";
import { UserContext } from "../App";

function Login() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [inputType, setInputType] = useState("password");
  const [icon, setIcon] = useState(<FaEye />);
  const [success, setSuccess] = useState("");

const {state, dispatch} = useContext(UserContext);

  function handleToggle(e) {
    if (inputType === "password") {
      setInputType("text");
      setIcon(FaEyeSlash);
    } else {
      setInputType("password");
      setIcon(FaEye);
    }
  }

  function handleSubmit(e) {
    e.preventDefault();

    const user = { email, password };
    console.log(`email: ${email}, password: ${password}`);
    axios
      .post("http://localhost:5000/user/login", user)
      .then((res) =>{
        console.log(res.data.user)
        dispatch({ type: "USER",payload: {name: res.data.user, logStatus: true, identity: res.data.identity}});
        if ((res.data.identity.id === "Admin") && (res.data.identity.approved === false)){
          setSuccess(
            `${res.data.user},please wait for the Admins to approve your account!`
            );
        }else{
            setSuccess(
              `welcome ${res.data.user} you are successfully Logged in!`
            );
        }
      }
      )
      .catch((err) => {
        //console.log(`ERROR is ${err}`);
        setSuccess("Incorrect password or email");
      });
  }

  if(state.logStatus){
   return <Navigate to="/profile" state={{mes: success }} />
  }

  return (
    
    <form onSubmit={handleSubmit}>
      <div className="text-center text-lg text-red-500 font-semibold">{success}</div>
      <div className="h-auto w-5/12 border mx-auto rounded-2xl mt-3 ">
        <div className="h-2 bg-indigo-400 rounded-t-2xl mb-5 "></div>
        <div className="font-bold text-2xl text-center">Sign In</div>
        <div className="px-16">
          <div className="mt-5 ">
            <label htmlFor="email" className="block font-semibold  ">
              Email address
            </label>
            <input
              type="email"
              className="border h-5 w-full px-3 py-5 rounded-md focus:outline-2 focus:outline-blue-600"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="Enter email"
              id="email"
              required
            />
          </div>

          <div style={{position: 'relative'}}>
            <label
              htmlFor="pass"
              className="block font-semibold mt-5"
            >
              Password
            </label>
            <input
              type={inputType}
              className="border h-5 w-full px-3 py-5 rounded-md focus:outline-2 focus:outline-blue-600"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              placeholder="Enter password"
              id="pass"
              required
            />
            <span style={{position: 'absolute', top:36, right:15}} onClick={handleToggle}>
              {icon}
            </span>
          </div>

          <div className="">
            <button
              type="submit"
              className="mt-5 text-white bg-blue-600 border h-10 w-full py-2 rounded-md"
            >
              Submit
            </button>
          </div>
          <div className="flex justify-around">
            <p className="mb-5 mt-3 text-left">
              New here?
              <Link to="/sign-up" className="text-blue-600">
                Register
              </Link>
            </p>
            <p className="mb-5 mt-3 text-right ">
              Forgot
              <Link to="/password-reset" className="text-blue-600">
                password?
              </Link>
            </p>
          </div>
        </div>
      </div>
    </form>
  );
}
  


export default Login;

I think there is an inconsistency in your code.

Try this:

const [Icon, setIcon] = useState(FaEye);
<span style={{position: 'absolute', top:36, right:15}} onClick={handleToggle}>
   <Icon />
</span>

FaEye is a reference to a function/class(component) which returns JSX element <FaEye />

As you can see, those two things are completely different. Basically, in one case you are passing a reference to a function and in the other you are passing the return value of that function.

1 Like

I would put that logic inside the JSX. Use a ternary and render the icons depending on the value of inputType. That also saves you on a state variable.

that has given me a clue and do not remember why i forget to put them like a component with between the tags < />,and indeed that is what has worked for me!

but this does not work even if i use
const [Icon, setIcon] = useState("FaEye");
it just gives me another error.

React docs: Choosing the Type at Runtime

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.