Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add active class/state for li element in ReactJS?

Tags:

I'm struggling with one issue all day long... I have list of books and after click user can see details of each books. I want to add background-color when element li is clicked (something like an active class). I use Redux and React and have no idea what is the best approach to create this feature. Please, give me some hints because I'm getting discouraged to React environment...

book-list.js

class BookList extends Component {
    renderList(){
        return this.props.books.map((book) => {
            return (
                <li key={book.title} 
                    className="list-group-item" 
                    onClick={() => this.props.selectBook(book)}>
                    {book.title}
                </li>
            )
        })
    }

render () {
    return (
        <div>
            <h3 className="m-t-2 m-b-1">Books to read:</h3>
            <ul className="list-group col-sm-4">
                {this.renderList()}
            </ul>
        </div>
    );
 } 
}

function mapStateToProps (state) {
    return {
        books: state.books
    };
 }

function mapDispatchToProps(dispatch) {
    return bindActionCreators({ selectBook: selectBook }, dispatch)
}

export default connect (mapStateToProps, mapDispatchToProps)(BookList); 

reducer_active_book.js

export default function(state = null, action) {
    switch(action.type) {
    case 'BOOK_SELECTED':
        return action.payload;
    }
        return state;
}

actions.js

export function selectBook (book) {
    return {
        type: 'BOOK_SELECTED',
        payload: book
    }
}
like image 473
Italik Avatar asked Apr 17 '18 11:04

Italik


2 Answers

You can use classnames package https://github.com/JedWatson/classnames

import classNames from 'classnames';

return this.props.books.map((book) => {
        return (
            <li key={book.title} 
                className={classnames({'list-group-item':true, 'active': book.active})} 
                onClick={() => this.props.selectBook(book)}>
                {book.title}
            </li>
        )
    })

active class will affect only if book.active is true

//EDIT you have to pass reducer_active_book property from your state through mapStateToProps

function mapStateToProps (state) {
return {
    books: state.books,
    reducer_active_book: state.reducer_active_book,
};

}

Now in render you can use this.

return this.props.books.map((book) => {
        return (
            <li key={book.title} 
                className={classnames({'list-group-item':true, 'active': this.props.reducer_active_book.id === book.id})} 
                onClick={() => this.props.selectBook(book)}>
                {book.title}
            </li>
        )
    })
like image 86
Subin Sebastian Avatar answered Sep 28 '22 19:09

Subin Sebastian


<li key={book.title} 
    className={"list-group-item " + (book.flag ? 'active-class' : 'inactive-class')}
    onClick={() => this.props.selectBook(book)}>
    {book.title}
</li>

Try setting a 'flag' when one book is selected, and conditionally add style classes(active-class/inactive-class) accordingly

like image 35
LMenon Avatar answered Sep 28 '22 19:09

LMenon