1

I want to change the style of buttons when clicked on them.

Below are my files.

App.js:

class Test extends Component {
  constructor(){
         super();
         this.state = {
              black: true
         }
    }
    changeColor(){
        this.setState({black: !this.state.black})
    }
    render(){
        let btn_class1 = this.state.black ? "blackButton" : "whiteButton";
        let btn_class2 = this.state.black ? "whiteButton" : "blackButton";
        let btn_class3 = this.state.black ? "whiteButton" : "blackButton";

        return (
             <div>
                 <button className={btn_class1}
                         onClick={this.changeColor.bind(this)}>
                           Button1
                  </button>
                  <button className={btn_class2}
                         onClick={this.changeColor.bind(this)}>
                           Button2
                  </button>
                  <button className={btn_class3}
                         onClick={this.changeColor.bind(this)}>
                           Button3
                  </button>
             </div>
        )
    }
}
export default App;

color.css:

button{
  width: 80px;
  height: 40px;
  margin: 15px;
}
.blackButton{
  background-color: black;
  color: white;
}

.whiteButton{
  background-color: white;
  color: black;
}

At the start I want my button1 to have a black background, and button2 and button3 should have a white background.

When I click on button2, then it should have black background, and button1 and button3 should have white background.

Similarly with button3: when clicked upon, it should have a black background, and button1 and button2 should change to a white background.

3 Answers 3

1

METHOD 1
A straightforward way is to maintain a state which contains the name of the dark button since at a time only one button is dark and then on the onlick of the buttons pass the btn name to a function which sets that state with this button name. It'll hold the name of the dark button
Then add the className to the btns by comparing to the current state of the darkButton

class Test extends Component {
  constructor() {
    super();
    this.state = {
      darkBtn: "btn1"
    };
  }

  changeColor = (btn) => {
    this.setState({ darkBtn: btn });
  };

  addDarkClass = (btn) => {
    if (this.state.darkBtn === btn) return "blackButton";
    else return "whiteButton";
  };

  render() {
    return (
      <div>
        <button
          className={this.addDarkClass("btn1")}
          onClick={this.changeColor.bind(this, "btn1")}
        >
          Button1
        </button>
        <button
          className={this.addDarkClass("btn2")}
          onClick={this.changeColor.bind(this, "btn2")}
        >
          Button2
        </button>
        <button
          className={this.addDarkClass("btn3")}
          onClick={this.changeColor.bind(this, "btn3")}
        >
          Button3
        </button>
      </div>
    );
  }
}

export default Test;



Here I've created a function for adding the dark class, which will accept the btn name and then return the dark of white class by comparing to the current state value.

METHOD-2
If you button doesn't have much individual properties then map can be used.

class Test extends Component {
  constructor() {
    super();
    this.state = {
      darkBtn: 0
    };
  }

  changeColor = (btn) => {
    this.setState({ darkBtn: btn });
  };

  btns = ["Button1", "Button2", "Button3"];

  render() {
    return (
      <div>
        {this.btns.map((btn, i) => (
          <button
            key={i}
            onClick={this.changeColor.bind(this, i)}
            className={this.state.darkBtn === i ? "blackButton" : "whiteButton"}
          >
            {btn}
          </button>
        ))}
      </div>
    );
  }
}

export default Test;
Sign up to request clarification or add additional context in comments.

Comments

0

You can do something a lot simpler than that. use state to save the current active button's index. Create an array of whatever size you want. itereate over it using .map function to create your buttons. Make the active button the one that it's index equals to the state's active variable.

class Test extends Component {
  constructor(){
         super();
         this.state = {
              active: 0
         }
    }
    changeColor = (i) => {
        this.setState({active: i})
    }
    render(){
        return (
             <div>
                 {Array.apply(null, Array(3)).map((el, i) => {
                 const active = this.state.active === i
                 <button key={i} className={active ? 'blackButton' : 'whiteButton'}
                         onClick={() => this.changeColor(i)}>
                           `Button${i + 1}`
                  </button>
             </div>
        )
    }
}
export default App;

Comments

0

It's working

import React, { useState } from 'react';   
import './App.css';
const App = () => {
  const [current, setCurrent] = useState(0);

  const renderComp = () => {
    return [0, 1, 2].map(el => {
      return <button 
      className={el === current ? 'blackButton': 'whiteButton'} 
      onClick={()=> setCurrent(el)}
      key={el} > {`Button${el+1}`} </button>
    })
  }

  return (
    <div>
      {renderComp()}
    </div>
  )
}

1 Comment

Choose only "answers" are discouraged on SO. kindly highlight important parts of your solution, and explain how/why it solves/addressed the OP's issue. Moist points come from future visitors who learned something from your explanation that they could apply to solve their own coding issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.