How to Toggle Input Field Values With React Hooks
Published: 2020-12-11 18:08:53

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.

```react
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;
```

 ## 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:

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

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:

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

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](https://codesandbox.io/s/muddy-smoke-shh2n?file=/src/App.js)