Commando
Commando

Reputation: 358

how to toggle with react hooks

I have 2 buttons that can be toggled by that simple hook:

  const [extendDetails, setExtendDetails] = useState(false);
  const handleExtendDetails = () => setExtendDetails(!extendDetails);

  const [extendPictures, setExtendPictures] = useState(false);
  const handleExtendPictures = () => setExtendPictures(!extendPictures);

And these are the buttons:

<button onClick={handleExtendDetails}>Extend Details</button>
<button onClick={handleExtendPictures}>Extend Pictures</button>

Is there some sort of way to name the buttons and use e or some kind of a variable so I won't need to declare a hook for each button in case I've got 20 buttons and not just 2?

Upvotes: 0

Views: 897

Answers (2)

Naren
Naren

Reputation: 4480

You can try using defining simple Object and target name combination.

const initialState = () => ({
  extendDetails: false,
  extendPictures: false
})

export default function App() {
  const [toggle, setToggle] = useState(initialState())

  const handleToggle = (e) => {
    const { name } = e.target

    setToggle({ ...toggle, [name]: !toggle[name] })
  }
  return (
    <div>
      <button name="extendDetails" onClick={handleToggle}>{toggle.extendDetails ? 'Open' : 'Close' } Extend Details</button>
      <button name="extendPictures" onClick={handleToggle}>{toggle.extendPictures ? 'Open' : 'Close' } Extend Pictures</button>
    </div>
  );
}

Demo link is here

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 371168

One option is to use an array instead:

const [toggledButtons, setToggledButtons] = useState(() => Array.from(
  { length: 20 },
  () => false
));

Then you could do something like

const toggle = (i: number) => () => setToggledButtons(
    toggledButtons.map((current, j) => i === j ? !current : current)
);
<button onClick={toggle(0)}>Extend Details</button>
<button onClick={toggle(1)}>Extend Pictures</button>

Upvotes: 1

Related Questions