Use click handler to change color of button when there are multiple buttons using the same function

4.4k views Asked by At

I have three buttons using the same click handler. - My desire is to only change the color of one button when clicked.

If another button is clicked I want the previously clicked button to go back to the color 'blue' (original state).

Example code below:

import React, { useState } from 'react';

export default function App() {
    const [state, setState] = useState({
        name: 'bob',
        color: 'blue',
    });

    const handleColor = (e) => {
        setState((state) => ({
            ...state,
            color: 'red',
        }));
    };


    return (
        <div>
         <button style={{ backgroundColor: state.color }} onClick={handleColor}>Click Me</button>
         <button style={{ backgroundColor: state.color }} onClick={handleColor}>Click Me 2</button>
         <button style={{ backgroundColor: state.color }} onClick={handleColor}>Click Me 3</button>
        </div>
    );
}
3

There are 3 answers

5
akhtarvahid On BEST ANSWER

Are you looking something like this

const lists = [
  { id: 1, title: "Click 1" },
  { id: 2, title: "Click 2" },
  { id: 3, title: "Click 3" }
];
export default function App() {
  const [selected, setSelected] = useState(0);
  const [state, setState] = useState({
    name: "bob",
    color: "blue"
  });

  const handleColor = (row) => {
    setSelected(row.id);
  };

  return (
    <div>
      {lists.map((list) => (
        <button
          key={list.id}
          onClick={() => handleColor(list)}
          style={{ backgroundColor: list.id === selected ? "red" : "" }}
        >
          {list.title}
        </button>
      ))}
    </div>
  );
}

Live working demo

0
ray On

If you only want one button active at a time, keep track of which one is active instead of what color it is.

// hypothetical list of buttons. these could be objects with labels, etc.
// but for the purposes of this example they're just empty slots.
const buttons = Array(3);

// the index of the currently active button
const [active, setActive] = useState();

return (
  <div>
    { buttons.map((button, index) => ( // render a button for each item in the array
      <button
        style={active === index ? { backgroundColor: 'red' } : {}}
        onClick={() => setActive(index)}>
          Click Me
      </button>
    )}
  </div>
)

0
Mohammad Faisal On

you have to maintain separate state for each button. you can do something like this

import React, { useState } from 'react';

export default function Parent() {

    const initialButtonState = {
        color1: 'blue',
        color2: 'blue',
        color3: 'blue',
    } 


    const [state, setState] = useState({...initialButtonState , name: 'bob'});

    const handleColor = (colorName) => {
        setState((state) => ({
            ...state,
            ...initialButtonState ,
            [colorName] : 'red'
        }));
    };


    return (
        <div>
         <button style={{ backgroundColor: color1 }} onClick={ () => handleColor("color1))}>Click Me</button>
         <button style={{ backgroundColor: color2 }} onClick={() => handleColor("color2")}>Click Me 2</button>
         <button style={{ backgroundColor: color3 }} onClick={() => handleColor("color3")}>Click Me 3</button>
        </div>
    );
}