How can I change 2 different variables independently with a single function in React?

Viewed 25

I'm new to React and I have a short and stupid question, but my poor phrasing makes it so that I haven't been able to find the answer by searching for it.

Basically, I have 2 password fields. I want to show and hide each one independently, but I would like a more elegant way than having 2 different functions with their own variables like this:

  const [showPassword1, setShowPassword1] = useState(false);
  const [showPassword2, setShowPassword2] = useState(false);

  const togglePasswordVisiblity1 = () => {
    setShowPassword1(showPassword1 ? false : true);
  };
  const togglePasswordVisiblity2 = () => {
    setShowPassword2(showPassword2 ? false : true);
  };

With the respective buttons below:

<span onClick={togglePasswordVisiblity1}>Show/Hide</span>
<span onClick={togglePasswordVisiblity2}>Show/Hide</span>

I'm sure there's a way to regroup these into a single function that changes the right variable based on which span is clicked, but I haven't had any luck finding the syntax. Sorry again for this question, hopefully it can be answered quickly!

Thanks in advance for your help.

2 Answers

You can try to use an array for the state. Check this sandbox demo:

import React, { useState } from "react";

export default function App() {
  const [showPassword, setShowPassword] = useState([false, false]);

  return (
    <div className="App">
      <button
        onClick={() => setShowPassword([!showPassword[0], showPassword[1]])}
      >
        {JSON.stringify(showPassword[0])}
      </button>
      <button
        onClick={() => setShowPassword([showPassword[0], !showPassword[1]])}
      >
        {JSON.stringify(showPassword[1])}
      </button>
    </div>
  );
}

Refactored version by extracting state update into a function:

import React, { useState } from "react";

export default function App() {
  const [showPassword, setShowPassword] = useState([false, false]);

  const togglePassword = (idx) => {
    const newShowPassword = [...showPassword];
    newShowPassword[idx] = !newShowPassword[idx]; // toggle
    setShowPassword(newShowPassword); // update the state
  };

  return (
    <div className="App">
      <button onClick={() => togglePassword(0)}>
        {JSON.stringify(showPassword[0])}
      </button>
      <button onClick={() => togglePassword(1)}>
        {JSON.stringify(showPassword[1])}
      </button>
    </div>
  );
}

const [state , setState] = useState({
    showPassword1:false,
    showPassword2: false
})

const togglePasswordVisiblity1= e => {
    const {name , value} = e.target
    setState( prevState => ({
        ...prevState,
       [name]: prevState[name] ? false : true
    }))
}

//

<span name='showPassword1' onClick={togglePasswordVisiblity1}>Show/Hide</span>
<span name='showPassword2' onClick={togglePasswordVisiblity1}>Show/Hide</span>
Related