Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REACT: toggle class onClick, and call other function

I am new to react so please be patient - I'm sure this is a simple problem but I am having a lot of trouble figuring out a solution.

I have a set of buttons, when they are clicked I add an 'active' className to that button and remove it from any other buttons that might be active.

I also need to open a panel with content based on which button is clicked.

So far I have managed to toggle the className of the clicked button, but can't figure out how to only apply it to the button that is clicked (see code below)

<a onClick={this.buttonClick(1)} className={this.state.isButtonActive ? 'active' : null}>button text</a>
<a onClick={this.buttonClick(2)} className={this.state.isButtonActive ? 'active' : null}>button text</a>

and the function to toggle the active state and open appropriate panel based on the button clicked:

buttonClick(buttonNumber) {

    this.setState(prevState => ({
        isButtonActive: !prevState.isButtonActive
    }));

    openPanel(buttonNumber)
}

I have experimented with creating a child component for the button and toggling the className within the component, but then I can't trigger the openPanel() function as it is in the parent component.

I hope that makes sense - thank you in advance :)

like image 254
ronnie burns Avatar asked Jan 30 '23 16:01

ronnie burns


1 Answers

the problem is that you are sharing the same state for both buttons, so when you change it for one, it changes for the other. You should wrap your buttons in different components so that they have different state.

If you need a callback in the parent component to be called, pass it to the button components so that they can trigger that as well.

The button could look like this:

class Button extends React.Component {
  constructor () {
    super()
    this.state = { isButtonActive: false }
    this.onClick = this.onClick.bind(this)      
  }

  onClick () {
    this.setState({
      isButtonActive: !this.state.isButtonActive
    })

    this.props.openPanel(this.props.buttonNumber)
  }

  render () {

    return (
      <button onClick={this.onClick()} className={this.state.isButtonActive ? 'active' : null}>button text</a>
    )
  }
}

how the parent component could look like:

class Parent extends React.Component {
  onButtonClicked (number) {
    console.log(`Button ${number} was clicked`)
  }

  render () {
    return (
      <div>
        <Button buttonNumber={1} openPanel={this.onButtonClicked} />
        <Button buttonNumber={2} openPanel={this.onButtonClicked} />
      </div>
    )
  }
like image 164
Mario F Avatar answered Feb 03 '23 06:02

Mario F