Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add class to specific element in React onClick

I use react-slick carousel with custom controls. I want to add 'active' class only to element that is changes the slide (by onClick event). But in my case 'active' class toggles for all of them.

export default class ServicesSlider extends React.Component {
    constructor(props) {
        super(props)
        this.changeSlide = this.changeSlide.bind(this)
        this.state = {
            isActive: false
        }
    }
    changeSlide(e) {
        this.setState({
            isActive: !this.state.isActive
        });
        this.slider.slickGoTo(e);
    }
    render() {
        return (
            <div>
                <section className="carousel-controls">
                    <div
                        onClick={() => this.changeSlide(0)}
                        className={this.state.isActive
                        ? 'column' : 'column active'}>Slide one
                    </div>
                    <div
                        onClick={() => this.changeSlide(1)}
                        className={this.state.isActive
                        ? 'column' : 'column active'}>Slide two
                    </div>
                    <div
                        onClick={() => this.changeSlide(2)}
                        className={this.state.isActive
                        ? 'column' : 'column active'}>Slide three
                    </div>
                    <div
                        onClick={() => this.changeSlide(3)}
                        className={this.state.isActive
                        ? 'column' : 'column active'}>Slide four
                    </div>
                </section>
                <Slider ref={c => this.slider = c}>
                    <div className="sliderItem">Slide 1</div>
                    <div className="sliderItem">Slide 2</div>
                    <div className="sliderItem">Slide 3</div>
                    <div className="sliderItem">Slide 4</div>
                </Slider>
            </div>
        )
    }
}

How to properly append class to a specific element in React?

like image 871
fadeouter Avatar asked Aug 04 '17 14:08

fadeouter


2 Answers

The key is to not keep track of a boolean active, but of the active index. That is, which slide is active: 0, 1, 2, 3, or 4, .... You will need to modify your state to achieve that.

I would also advocate changing the parameter from e to something more descriptive, as e is generally used for events.

If you change your state to

this.state = {
    activeIndex: 0
}

then you can update the active value as such:

changeSlide(index) {
    this.setState({
        activeIndex: index
    });
    this.slider.slickGoTo(index);
}

and then check for active in render:

<div
    onClick={() => this.changeSlide(0)}
    className={this.state.activeIndex !== 0 ? 'column' : 'column active'}>
    Slide one
</div>
like image 87
Wolfie Avatar answered Sep 23 '22 00:09

Wolfie


Rather than having an isActive variable, which suggests only a true/false value, why not have a currentActiveSlide variable?

In the constructor you initiate it as null (if you want your App to start with no active slide). And then update it with the index when you click it.

So your changeSlide() function becomes:

changeSlide(idx) {
  // If we click on the already active slide, set "currentActiveSlide" to null.
  // Otherwise, set it to the "idx".
  this.setState({
    currentActiveSlide: idx !== this.state.currentActiveSlide ? idx : null
  });
  this.slider.slickGoTo(idx);
}

I changed your e parameter to idx for clarity. because the former suggests an event. Of course, you would need to update your render as well:

className={this.state.currentActiveSlide === 1 ? 'column' : 'column active'}

(though I think you got the logic reversed here).

like image 28
Chris Avatar answered Sep 23 '22 00:09

Chris