Home > Software engineering >  How to change the state of only one element in a map?
How to change the state of only one element in a map?

Time:09-19

I am learning react and I have stumbled upon a problem that I am trying to solve for several hours now but without any luck. I have an array of product sizes which I map to buttons. My goal is to change the state only of the last clicked button and to pass the value of the button to a variable. Currently whenever clicked, all buttons change their state.

import React, { useState } from "react";

export default function Button() {
  const sizes = [10, 11, 12, 13];
  const [btnState, setBtnState] = useState(true);

  const handleClick = () => setBtnState(!btnState);

  return (
    <div className="button-component">
      {sizes.map((size, index) => (
        <button className="btn" onClick={handleClick}>
          {size} {btnState.toString()}
        </button>
      ))}
    </div>
  );
}

Edit wizardly-shannon-3m2kso

CodePudding user response:

Issue

The issue here is that there is only the single state value and all the mapped buttons use the same state in the same way.

Solution

Convert the btnState to an object where the size is a dynamic key.

function Button() {
  const sizes = [10, 11, 12, 13];
  const [btnState, setBtnState] = useState({});

  const handleClick = (size) => () => setBtnState(sizes => ({
    ...size,
    [size]: !sizes[size]
  }));

  return (
    <div className="button-component">
      {sizes.map((size, index) => (
        <button className="btn" onClick={handleClick(size)}>
          {size} {String(!!btnState[size])}
        </button>
      ))}
    </div>
  );
}

Edit how-to-change-the-state-of-only-one-element-in-a-map

If you want only a single active state then store just the passed size in the callback handler in state and check it's value when mapping.

function Button() {
  const sizes = [10, 11, 12, 13];
  const [btnState, setBtnState] = useState();

  const handleClick = (size) => () =>
    setBtnState(size);

  return (
    <div className="button-component">
      {sizes.map((size, index) => (
        <button className="btn" onClick={handleClick(size)}>
          {size} {String(btnState === size)}
        </button>
      ))}
    </div>
  );
}

Edit how-to-change-the-state-of-only-one-element-in-a-map (forked)

  • Related