5

I am new to React. I have a few buttons in a button group:

<div className="btn-group">
    <button className="btn btn-mini btn-default" onClick={() => this.changeDataType("type1")} >Button1</button>
    <button className="btn btn-mini btn-default" onClick={() => this.changeDataType("type2")} >Button2</button>
    <button className="btn btn-mini btn-default" onClick={() => this.changeDataType("type3")} >Button3</button>
</div>

Whenever the user clicks on one of the buttons, this button should become the active, selected one. I found out that I need to add the CSS class active to the corresponding button, but I am not sure how to implement this.

I thought about this for a bit. I have a changeDataType function connected to my buttons, in which I do some other stuff. Would I then, in there, somehow manipulate the CSS?

So I guess my questions are first, how to target the button I need to target, and second, how I could change that button's CSS with React.

ROOT
  • 11,363
  • 5
  • 30
  • 45
George Welder
  • 3,787
  • 11
  • 39
  • 75

3 Answers3

5

In react when state changes react re-renders. In your case if you want to change the way something looks then you probably want to force another render. What you can do is have the className be part of state and then update the state when you want, causing the component to re-render with the new className. For example:

constructor() {
    super();
    this.state = {
        className: 'btn'
    }
}

render () {
    return (
        <Button className={this.state.className}>Click me</Button>
    )
}

Since the className is bound to state updating state will cause the button to render again with the new className. This can be done like this:

updateClass() {
    let className = this.state.className;
    className = className + ' ' + 'btn-primary'
    this.setState({className})
}

This is an example of the function you can call on the click of a button and update the className for the button.

Chaim Friedman
  • 6,124
  • 4
  • 33
  • 61
  • thanks a lot, that makes sense to me. so in my case I would just add the `active` to my className, stored in the state. However, how would I delete this again from the element which I no longer want to be the active one? – George Welder May 04 '17 at 15:57
  • The first approach that comes to mind is checking to see what the class name is of the current clicked button and and respond accordingly. – Chaim Friedman May 04 '17 at 15:58
3

There's a nice utility you can use for classname logic + joining classNames together

https://github.com/JedWatson/classnames

Based on setting React state for active you could do something like the following. You can get as complex as you need to with the logic. If the logic result is falsy, that key won't be included in the output.

var classNames = require('classnames');

var Button = React.createClass({
  // ...
  render () {
    var btnClass = classNames({
      btn: true,
     'btn-active': this.state.isActive
    });
    return <button className={btnClass}>{this.props.label}</button>;
  }
});
Tim Arney
  • 1,776
  • 2
  • 18
  • 23
  • Using a third-party lib here seems overkill for such a small thing. – lux May 04 '17 at 19:54
  • 3
    Computing class names is such a common thing to do in components, and `classnames` has simple functionality, that I find this reasonable. It might seem like overkill for an isolated example, but you'll use the `classnames` package many many times in a project. – Ross Allen May 04 '17 at 22:29
  • Here's thread with many more solutions https://stackoverflow.com/questions/34521797/how-to-add-multiple-classes-to-a-reactjs-component – keemor Jan 30 '19 at 14:10
0

Here how I did this:

//ChatRoomPage component

function ChatRoomPage() {

 const [showActionDropdown, setShowActionDropdown] = useState('hide');

  function showActionDropdownHandler(){
    console.log("clicked")
    if(showActionDropdown=='hide')
      setShowActionDropdown('show')
    else
      setShowActionDropdown('hide')

  }


 return (

    <div>

           <button onClick={ () => showActionDropdownHandler() } className="btn " type="button">Actions</button>

        <div className={`action_menu ${showActionDropdown}`}>
          ...
        </div>

   </div>
 );

}
export default ChatRoomPage;
Muhammad Shahzad
  • 9,340
  • 21
  • 86
  • 130