vsoni
vsoni

Reputation: 497

Add class to individual button using react Hook

I am trying to add css class to an active button but with below code it added to all buttons. So right not I am having two buttons and upon click it has added code to both buttons instead of one which is clicked.

What am I missing here.

import React, { useState } from 'react'

export default function ProductPage() {

  const [size, setSize] = useState('')
  const [color, setColor] = useState('')
  const [isActive, setActive] = useState(false)

  const toggleClass = () => {
     setActive(!isActive)
  }

  return (
    <>
        <div className="grid grid-cols-2 gap-10 p-14">
                      {productSizes.map((size,index) => {
                            return (
                                <button className={`hover:bg-black hover:text-white cursor-pointer ${isActive ? 'bg-black text-white' : null}`} role="button" tabIndex={0} 
                                onClick={() => {toggleClass(); setSize(size)}}
                                onKeyDown={() => setSize(size)} key={index}>{size}</button>
                            )
                        }
                    )}
                </div> 
                <div className="colors mb-8">
                    <p className="tracking-wider mb-2">Color</p>
                    {productColors.map(color => {
                        return (
                            <span className="p-2 border-gray-200 border mr-2 hover:bg-black hover:text-white cursor-pointer" role="button" tabIndex={0} onClick={() => setColor(color)} onKeyDown={() => setSize(size)} key={color.id}>
                             {color}
                            </span>
                        )
                        }
                    )}
                </div>  
               
                <button className="btn bg-green-500 mt-4 snipcart-add-item p-4 rounded text-white">
                        Add to cart
                </button>

    </>
  )
}

Upvotes: 1

Views: 861

Answers (1)

Drew Reese
Drew Reese

Reputation: 202846

Issue

You are using a single boolean isActive value to mark a button active or not, so because of this all buttons are active/inactive together.

Solution

Store an isActive state value that you can correlate to a specific button. I suggest using the index.

function ProductPage() {
  ...
  const [isActive, setActive] = useState(null); // <-- initial null state

  const toggleClass = (index) => {
    // toggle active/inactive index
    setActive((isActive) => (isActive === index ? null : index));
  };

  return (
    <>
      <div className="grid grid-cols-2 gap-10 p-14">
        {productSizes.map((size, index) => {
          return (
            <button
              className={`hover:bg-black hover:text-white cursor-pointer ${
                isActive === index ? "bg-black text-white" : null // <-- check index match
              }`}
              onClick={() => {
                toggleClass(index); // <-- pass index to toggle handler
                setSize(size);
              }}
              onKeyDown={() => setSize(size)}
              key={index}
            >
              {size}
            </button>
          );
        })}
      </div>

      ...

    </>
  );
}

Upvotes: 2

Related Questions