Apply style only to the clicked button

Hello, again.
I am trying to make button change its background color onMouseDown so the user could know when the button is clicked. The problem is, all of my buttons change the color at the same time (since I have multiple products). Can someone tell me how can I stop this from happening?
I have some clues how to achieve this, but honestly I don’t know how to implement it yet.

import React, { useState }  from "react";
import "./VinylClocks.css";
import { Link } from "react-router-dom";
import { addItem } from '../features/cart/cartSlice.js';
import { useDispatch } from 'react-redux';

export default function Product({filteredAndSortedList}) {
    const dispatch = useDispatch();
    const onClickHandler = (item) => {
    dispatch(addItem(item));
  };
  const [isMouseDown, setIsMouseDown] = useState(false);
 
  const handleMouseDown = () => {
      setIsMouseDown(true);
  };

  const handleMouseUp = () => {
      setIsMouseDown(false);
  };

  const containerStyle = {
      backgroundColor: isMouseDown ? '#D1DBE6' : 'transparent',
      fontFamily: 'Roboto, sans-serif',
      fontWeight: 'bold',
      color: '#284766',
      border: '5px double #284766',
      padding: '.3rem',
      width: '8rem',
  };
    return (
        <>
            {filteredAndSortedList.map(item => (
            <div className="products-card" key={item.id}>
                <Link to={`/product/productpage/${item.name}`}><img src={item.img}/></Link>
                <div className="name-price-tag">
                    <div className="price-container">
                        <p className="name">{item.name}</p>
                        {item.onsale === true ?
                            <div className="price-newprice">
                            <span className="price">$<del>{item.price}</del></span>
                            <span className="price">${item.newprice}</span>
                            </div>
                            : <span className="price">${item.price}</span>
                        }
                    </div>
                    <button
                            style=
                            {containerStyle}
                            onClick={() => onClickHandler(item)}
                            onMouseDown={handleMouseDown}
                            onMouseUp={handleMouseUp}
                            id="addToCart"
                        >
                            Add to Cart
                        </button>
                </div>   
            </div>
          
          ))}  
        </>
    )        
}

Hi,

This is more of an html and css kind of consideration (always remembering that at the end of the day, React works on a virtual DOM, what you end up seeing as the final product is a result of the actual DOM, javascript - What is Virtual DOM? - Stack Overflow).

So in pure html/css, you have tags that can be described by unique identifiers (id) or class identifiers (class). If you make a change to a class of something, you affect all the members, and if you make a change to an id, you only change the identified instance.

So the hint is that when you declare each component

<Button id="btn1" />
<Button id="btn2" />
<Button id="btn3" />

the component code should have access to the unique identifier of that particular component’s instance, so that when it makes changes to one it doesn’t apply it to the whole class.

1 Like

I understand that, but I’m not sure I can apply that here since I am mapping over an array of objects, which determines number of buttons I have. I was thinking about using filter or find, but not sure how in this particular case.

As you map and dynamically create the objects, you have access to some index and you can use that to still uniquely give them id names.

Pseudocode, you can turn it into legal jsx with a little adjustment

map((element, idx) => 
{  
   <Button id=`btn-${idx}` />
}
1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.