1

I have a React project where I am trying to build a carousel. I have both a button left and right and some circles under my carousel to select slides individually.

To change the slides in the carousel I am using a combination of intervals and timeouts to play a slide animation as well as to make sure it runs in a loop if the user does not click anything:

changeImageTimer(index = 0) {
    end = new Date().getMilliseconds();
    console.info(end - start);
    setTimeout(()=> {
        this.addAnimation();
    }, this.props.timeToChangeImage - this.props.timeOfTransitionAnimation);
    animationTimeout = setTimeout(() => {
        if (this.state.index >= this.props.data.length - 1) {
            index = 0;
        } else {
            index = this.state.index + 1;
        }
        this.setState({index: index});
        this.removeAnimation();
    }, this.props.timeToChangeImage);
    animationInterval = setInterval(() => {
        setTimeout(()=> {
            this.addAnimation();
        }, this.props.timeToChangeImage - this.props.timeOfTransitionAnimation);
        animationTimeout = setTimeout(() => {
            if (this.state.index >= this.props.data.length - 1) {
                index = 0;
            } else {
                index = this.state.index + 1;
            }
            this.setState({index: index});
            this.removeAnimation();
        }, this.props.timeToChangeImage);
    }, this.props.timeToChangeImage);
}

The buttons to select an individual slide have this function attached:

clickSelector(index) {
    this.clearIntervalsAndTimers();
    this.setState({index: index});
    start = new Date().getMilliseconds();
    timeout = setTimeout(this.changeImageTimer(index), this.props.timeToHoldPictureAfterClick);
}

As you can see, I want the slide to stay and then after some time restart the automatic iteration of slides.

However, the 'changeImageTimer' code is run immediately after the 'clickSelector' function and is not run after the set timeout delay.

Why do I have this behavior?

Moritz Schmitz v. Hülst
  • 3,229
  • 4
  • 36
  • 63
  • `As you can see` - your code is very hard to understand. Show us `this.props` object. p.s `this` in `setTimeout` functions can be very misleading. – Andrew Evt Apr 26 '16 at 10:23

3 Answers3

2

It is because of the parameter. First argument of you function must be parameter reference. Hope this helps . Why is the method executed immediately when I use setTimeout?

To pass a parameter

 setTimeout(function() {
    this.changeImageTimer(index);
}, this.props.timeToHoldPictureAfterClick)

Hope this helps

Community
  • 1
  • 1
Rahul
  • 347
  • 3
  • 11
1

Your timeout calls a function, your passing it whatever changeImageTimer returns. Instead bind the function so the setTimeout gets a function preloaded with the args instead.

    timeout = setTimeout(this.changeImageTimer.bind(this, index), this.props.timeToHoldPictureAfterClick);

As an aside, if you set the timeouts as properties in your class it will be easier to clear them at later points.

this.timeout = setTimeout(this.changeImageTimer.bind(this, index), this.props.timeToHoldPictureAfterClick);
// ... later on in your code
clearTimeout(this.timeout)
Rob Wilkinson
  • 296
  • 1
  • 7
0

modify like this :

    timeout = setTimeout(this.changeImageTimer.bind(this,index), this.props.timeToHoldPictureAfterClick);
superui
  • 654
  • 5
  • 10