Murat Karagöz
Murat Karagöz

Reputation: 37604

ReactJs How to change an icon of a button on the click event?

I am using the IconButton from material-ui and I want to change the icon of the button after the click/touch event.

var tableModeElement =
<IconButton key="tableModeButton" 
 onTouchTap={() => { 
   this.setState(prevState => (
    { isCardView: !prevState.isCardView })) } }>
  <i className="material-icons theme-color-p1">
   {this.state.isCardView ? "view_module" : "list"}
  </i>
</IconButton>

The expression {this.state.isCardView ? "view_module" : "list"} is only evaluated once and no more after that. I thought if I change the state I will force a re-render? What am I doing wrong?

EDIT: added that the iconButton is assigned to a variable. If I include the <IconButton> directly into the render method it works fine. I had to re-assign the variable to make it work.

Upvotes: 4

Views: 19594

Answers (4)

Marty
Marty

Reputation: 2963

Setting text "view_module" or "list" in a <i> element will not change the icon for the button

You need to have a nested icon within the button, eg:

<IconButton key="tableModeButton" 
 onTouchTap={() => { 
   this.setState({
     isCardView: !this.state.isCardView
   })
  }}>
   {this.state.isCardView ? <IconA /> : <IconB /> }
</IconButton>

Upvotes: 2

skAstro
skAstro

Reputation: 374

The icon to be used by <IconButton> is defined by it's iconClassName prop.

It could look something like this afterwards.

<IconButton key="tableModeButton" 
  onTouchTap={() => { 
     this.setState( prevState => {isCardView: !prevState.isCardView} ) }
  }
  iconClassName={this.state.isCardView ? "view_module" : "list"} />
</IconButton>

Upvotes: 1

Chris
Chris

Reputation: 58292

I believe this would work:

class IconButton extends React.Component { 
  constructor(props) {
    super(props);
    this.state = {
      isCardView: false,
    }
  } 

  render() {
    return (
      <a className="btn btn-primary" onClick={()=>this.setState({ isCardView: !this.state.isCardView })}>
        { this.state.isCardView
          ? <span className="glyphicon glyphicon-remove-sign" />
          : <span className="glyphicon glyphicon-ok-sign" />
        }
        &nbsp;&nbsp;BUTTON
      </a>
    );
  }

}

class App extends React.Component { 
  render () {                                        
    return (
      <div>
        <IconButton />  
      </div>
    );
  }
}

ReactDOM.render(<App/>,document.getElementById('root'));

I'm using bootstrap, but any icon system would work

http://codepen.io/cjke/pen/MJvXNo?editors=0010

Upvotes: 4

Hajji Tarik
Hajji Tarik

Reputation: 1082

This is the best I could come up with :

     <IconButton key="tableModeButton" onTouchTap={(e) => { 

        let show = this.state.prevState.isCardView;
        let index = show.indexOf('show');

        if (index != -1) {
           show = 'hide';
        } else {
           show = 'show';
        }

        this.setState(prevState => ({ isCardView: show }));
        event.preventDefault()

} }>

Upvotes: 1

Related Questions