DEV Community

Cover image for How to Toggle Input Field Values With React Hooks
Margai Wangara(he/him)
Margai Wangara(he/him)

Posted on • Updated on

How to Toggle Input Field Values With React Hooks

I have been coding in React for some time now(a while, like a long while) and throughout this period, I have come across some awesome stuff. However, for some reason, every time I created an authentication form, I didn't really feel the need to provide the user with the need to view their password while or after their input. Recently, I decided to integrate that option(feature I guess) and this is how I did it(more or less). I'll be using React Hooks, because, well, they're awesome and I kind of don't like writing classes.

Concept

The main concept behind pulling this off is one word actually, toggling. Basically, what we want to do is this, when the user clicks on a certain icon/field/element, we change the state accordingly such that if the input type is password, we show text and vice versa. To achieve this, we initialize two state variables, inputValue and isInputVisible. We then check the state(pun intended) of these variables and display based on that. Don't forget the state-changing functions or state-setters if you will. We name them setInputValue and setIsInputVisible respectively.

import React, { useState } from 'react';
import view from "./assets/eye-regular.svg";
import hide from "./assets/eye-slash-regular.svg";

function App(){
    const [inputValue, setInputValue] = useState(''); // boilerplate React stuff
    const [isInputVisible, setIsInputVisible] = useState(false);

    return (
        <div style={style}>
          <form method="post" style={form}>
            <div style={div}>
              <input
                type={isInputVisible ? "text" : "password"}
                id="passwordField"
                style={input}
                value={inputValue}
                onChange={(e) => setInputValue(e.target.value)}
                placeholder="Password"
              />
              <span style={eye}>
                <span onClick={() => setIsInputVisible(!isInputVisible)}>
                  <img
                    src={isInputVisible ? hide : view}
                    alt="password-toggle"
                    style={img}
                  />
                </span>
              </span>
            </div>
          </form>
        </div>
    );
}

const style = {
  width: "100%",
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  height: "100vh"
};

const formStyle = {
  form: {
    display: "flex",
    flexDirection: "column",
    width: "80%",
    margin: "0 auto"
  },
  div: {
    position: "relative"
  },
  input: {
    outline: "none",
    border: "solid 2px var(--secondary)",
    borderRadius: "10px",
    padding: "15px",
    backgroundColor: "#ddd",
    fontSize: "20px",
    width: "100%"
  },
  eye: {
    height: "100%",
    width: "25px",
    position: "absolute",
    right: "10px",
    top: 0,
    borderRadius: "50%",
    display: "flex",
    alignItems: "center",
    justifyContent: "center"
  },
  img: {
    height: "100%",
    width: "100%",
    cursor: "pointer"
  }
};

export default App;
Enter fullscreen mode Exit fullscreen mode

## Explaining the code

Just to get it out of the way, I added some in-line styling to, you know, spice things up a little bit.

The magic is within the <form> tags. Inside the input tag, we have some stuff going on:

 <input
     type={isInputVisible ? "text" : "password"}
     id="passwordField"
     style={input}
     value={inputValue}
     onChange={(e) => setInputValue(e.target.value)}
     placeholder="Password"
     />
Enter fullscreen mode Exit fullscreen mode

On the input type, we check if isInputVisible is true, if true, it means the user would like to view the password entered, we therefore change the type to text, else, we set the type to password, which is basically just a bunch of dots.

The value attribute is bound to state, which is modified by the next line onChange which modifies the state based on any change to the input element, in this situation, user input is the change. e.target refers to the input element, we then get the target's value.

We then have a span element, which just acts as the container to the image tag which contains the eye icon:

<span style={eye}>
    <span onClick={() => setIsInputVisible(!isInputVisible)}>
        <img
            src={isInputVisible ? hide : view}
            alt="password-toggle"
            style={img}
            />
    </span>
</span>
Enter fullscreen mode Exit fullscreen mode

Inside the img tag, we change the source src based on the state of the isInputVisible variable. If the isInputVariable is true, we show the hide(eye with a slash) icon, else, we show the view(eye) icon.

This variable's state is modified with an onClick event to the span, parent of the img tag. onClick, the setIsInputVisible function returns the negation of the isInputVisible variable meaning if isInputVisible is true, it returns false and vice versa.

I have attached a link to view the entire code and its result, two of the MISSING imports can be found in the attached link.

https://codesandbox.io/s/muddy-smoke-shh2n?file=/src/App.js

Discussion (0)