Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to correctly toggle type of password input to text or vice versa in React(next)

I have trouble toggling an input type between password and text to show the password in the login form.
The functionality is that when clicking on the eye icon on the password input it should show the password in plain text but this is not happening.
Technically speaking I am trying to change the type of password input to text without success.
This is the code:

  const [showPassword, setShowPassword] = useState(false)
  const passwordRef = useRef<HTMLInputElement>(null);

  const handleShowPassword = (ref: React.RefObject<HTMLInputElement>) => {
    if (ref.current && ref.current.id === 'password') {
      setShowPassword((prev) => !prev);
      if (showPassword) {
        ref.current!.type = "password";
        console.log('passwordRef.current?.type: ', ref.current?.type); // password
      } else {
        ref.current!.type = "text";
        console.log('passwordRef.current?.type: ', ref.current?.type); // text
      }
    }
  };

return (

<Container>
  <BackgroundBox />
  <FormBox>
  
      {/* Password */}
      <div className='auth-input-container login-password'>
        <FaKey className="auth-icon" size='20px' />
        <input
          type="password"
          id="password"
          name="password"
          placeholder="Enter password"
          className="auth-input"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.password}
          ref={passwordRef}
        />
        {
          showPassword ? <FaEyeSlash className="auth-icon-password-eye" onClick={() => handleShowPassword(passwordRef)} />
            : <FaEye className="auth-icon-password-eye" onClick={() => handleShowPassword(passwordRef)} />
        }
      </div>
      {formik.touched.password && formik.errors.password ? (
        <div className="error-message">{formik.errors.password}</div>
      ) : null}
// and closing tags

When I log the types in handleShowPassword it actually shows text or password as it should bu in the end the actual passwordRef type is not ever changing to text but always stays text.

The strange thing is that if I use Vanilla JS instead of useRef :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const handleShowPassword = (ref: React.RefObject<HTMLInputElement>) => {
const DOMref = document.getElementById('password') as HTMLInputElement;
if (DOMref.id === 'password') {
  console.log('DOMref: ', DOMref);
  if (DOMref.type === 'password') {
    DOMref.type = 'text'
  } else {
    DOMref.type = 'password'
  }
}

};

This would work fine.

How come? How to fix this problem?

>Solution :

You can achieve this by conditionally setting the input type as so:

const [showPassword, setShowPassword] = useState(false)

  const handleShowPassword = () => {
    setShowPassword(!showPassword);
  };

return (

<Container>
  <BackgroundBox />
  <FormBox>
  
      {/* Password */}
      <div className='auth-input-container login-password'>
        <FaKey className="auth-icon" size='20px' />
        <input
          type={showPassword ? "text" : "password"}
          id="password"
          name="password"
          placeholder="Enter password"
          className="auth-input"
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
          value={formik.values.password}
          ref={passwordRef}
        />
        {
          showPassword ? <FaEyeSlash className="auth-icon-password-eye" onClick={handleShowPassword} />
            : <FaEye className="auth-icon-password-eye" onClick={handleShowPassword} />
        }
      </div>
      {formik.touched.password && formik.errors.password ? (
        <div className="error-message">{formik.errors.password}</div>
      ) : null}
// and closing tags




Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading