0

I have a loop of multiple buttons, I want to change the background color of only the clicked button and not all of them as it happens here :

const [clicked, setClicked] = useState(false);

<div className="flex gap-4 flex-wrap">
    {times.map((time, i) => (
            <div
                key={`time-${i}`}
                className={`${clicked ? 'bg-slate-400' : 'bg-light-gold'}`}
                onClick={() => { setClicked(true) }
             >
                    {time}
            </div>
    ))}
</div>

Mer Mer
  • 83
  • 11

2 Answers2

2

Should check index of button clicked.

const [idClicked, setIdClicked] = useState(-1);

<div className="flex gap-4 flex-wrap">
    {times.map((time, i) => (
            <div
                key={`time-${i}`}
                className={`${idClicked === i ? 'bg-slate-400' : 'bg-light-gold'}`}
                onClick={() => { setIdClicked(i) }
             >
                    {time}
            </div>
    ))}
</div>
Doan Thai
  • 561
  • 3
  • 10
1

The UI should be driven by data. You need to create a button list data, each object contains the button's label, button's clicked status, etc...

When the button is clicked, change the value of clicked property of the button.

import './styles.css';
import React from 'react';

const initialTimes = [
    { label: 'button 1', clicked: false },
    { label: 'button 2', clicked: false },
    { label: 'button 3', clicked: false },
];

export default function App() {
    const [times, setTimes] = React.useState(initialTimes);
    return (
        <div className="App">
            <h1>Hello CodeSandbox</h1>
            <h2>Start editing to see some magic happen!</h2>

            <div>
                {times.map((time, i) => (
                    <button
                        key={`time-${i}`}
                        style={time.clicked ? { background: 'red' } : undefined}
                        onClick={() => {
                            const nextTimes = times.map((t, idx) => (idx === i ? { ...t, clicked: !time.clicked } : t));
                            setTimes(nextTimes);
                        }}>
                        {time.label}
                    </button>
                ))}
            </div>
        </div>
    );
}

codesandbox

Lin Du
  • 88,126
  • 95
  • 281
  • 483