user6002037
user6002037

Reputation:

Add className to li item react

I am trying to update the active class when a user clicks on a button. Each time this button is clicked on the next item should have the class name active added and removed from the previous one. Using jQuery I could use the addClass and removeClass methods. Something along these lines would get me started.

$("button").click(function() {
    $("ul li").removeClass("active");
   var length = $(this).prevAll().length;
   $("ul li:eq(" + length + ")").addClass("active");
});

I am not sure how I should go about implementing this using react.

I have set up a JSFIDDLE here.

var App = React.createClass({

    getInitialState: function(){

        return {
            active: 0
        }
    },

    incrementIndex: function() {
        this.setState({active : this.state.active + 1});    
    },

    render: function () {
        return(
            <div>
                <ArtistList active={this.state.active}  />
                <Button increment={this.incrementIndex} />
            </div>
        )
    }

});

var ArtistList = React.createClass({

    render: function() {

        return(
            <ul>
                <li className="active">Michael Jackson</li>
                <li>Bob Dylan</li>
                <li>Kendrick Lamar</li>
            </ul>
        )
    }

});

var Button = React.createClass({
    render: function() {
        return(
            <button onClick={this.props.increment}>next</button>
        )
    }
})

Upvotes: 0

Views: 5428

Answers (2)

finalfreq
finalfreq

Reputation: 6980

I would pass in artists as a prop to ArtistList, and then in AristList use a map function to generate a list of li's and use a ternary to figure out if it should be active or not.

have the pen here http://codepen.io/finalfreq/pen/bwoddN

var App = React.createClass({

    getInitialState: function(){
        return {
            active: 0
        }
    },

    incrementIndex: function() {
        this.setState({active : this.state.active + 1});    
    },

    render: function () {
      const artistList = ['Michael Jackson', 'Bob Dylan', 'Kendrick Lamar']
        return(
            <div>
                <ArtistList artists={artistList} active={this.state.active}  />
                <Button increment={this.incrementIndex} />
            </div>
        )
    }

});

var ArtistList = React.createClass({

    renderArtists: function() {
      var self = this;
      return this.props.artists.map(function(artist, index) {
        var classes = index === self.props.active ? 'active' : '';
       return <li key={index + artist} className={classes} > { artist } </li>
      });
    },

    render: function() {
        let artists = this.renderArtists();
        return(
            <ul>
              {artists}
            </ul>
        )
    }

});

var Button = React.createClass({
    render: function() {
        return(
            <button onClick={this.props.increment}>next</button>
        )
    }
})

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

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816334

You can generate the list elements dynamically by iterating over an array containing the list content. Then you can simply compare the passed prop with the current iteration:

var data = ['Michael Jackson', 'Bob Dylan', 'Kendrick Lama'];
var listItems = data.map((value, index) => (
  <li
    key={value} 
    className={this.props.active === index ? 'active' : ''}>
    {value}
  </li>
));

return <ul>{listItems}</ul>;

Upvotes: 1

Related Questions