36

I'd like to know how to use setTimeout() on ReactJS, because I'm doing this:

 timerid = setTimeout( () => this.reqMaq( obj['fkmaqid'] ), 2000 )

and it calls twice the function this.reqMaq().

How do I prevent the first call? and just keep the call after the time?

Here it's the Component:

reqMaq (maqid) {
    return fetch(`/scamp/index.php/batchprodpry/${maqid}`, {credentials: 'same-origin'})
      .then(req => {
        if (req.status >= 400) {
          throw new Error("Bad response from server")
        }
        return req.json()
      })
      .then(json => this.processMaqReq(json))
      .catch(function(error) {
        console.log('request failed', error)
      })
  }    

  handleChangeMaq (event) {
    event.preventDefault()
    if (event.target.value.length > 0) {
      let obj = this.state.obj
      obj['fkmaqid'] = VMasker.toPattern(event.target.value, "99-99-99-99")
      // if (timerid) {
      //   clearTimeout(timerid)
      // }
      // timerid = setTimeout(() => {
      //   if (!isRunning) {
      //     this.reqMaq(obj['fkmaqid'])
      //   }
      // }, 2000)
      const fx = () => this.reqMaq( obj['fkmaqid'] )
      timerid = setTimeout( fx, 2000 )
      this.setState({ obj: obj })
    }
  }
  render() {
    return (
      <div className="form-group">
              <label htmlFor="maquina">M&aacute;quina</label>
              <input type="text" className="form-control" id="maquina"
                name="maquina"
                placeholder="Maquina"
                value={this.state.obj['fkmaqid'] || ''}
                onChange={this.handleChangeMaq}
                ref={node => {
                  input1 = node
                }}
                required="required"
              />
            </div>
    )
  }

Thank you.

10
  • why is it called twice ? Do you call it on initialization ? Commented Aug 16, 2016 at 14:02
  • There must be some other context; on its own, this will call it once after 2s. Are you doing it in a lifecycle event? render method? Etc. Commented Aug 16, 2016 at 14:05
  • That setTimeout is being called on a onChange over a form field. What do you suggest? is it because of that? Commented Aug 16, 2016 at 14:07
  • I'm not calling it on init. I'm calling it on a onChange Commented Aug 16, 2016 at 14:08
  • 2
    Your problem is not this code, it's the method that holds this code and any other code that calls that method. Based only on what you've told us here, the simplest solution is to use a flag isRunning, which you set to true when you start the timer, set to false when your timer ends, and don't allow starting of the timer unless isRunning is false Commented Aug 16, 2016 at 14:39

3 Answers 3

65

Try this:

if (timerid) {
  clearTimeout(timerid);
}

timerid = setTimeout(() => {
  this.reqMaq(obj['fkmaqid'])
}, 2000);
Sign up to request clarification or add additional context in comments.

2 Comments

I had to declare a var in the state and then use it in the method where the setTimeout() resides
If I get it right you want to debounce the execution of the reqMaq function, but currently you are only delaying it, so if you type two letters you will run that function twice. Take a look at this stackoverflow.com/questions/23123138/…
3

This should do the trick

const fx = () => this.reqMaq( obj['fkmaqid'] )
timerid = setTimeout( fx, 2000 )

1 Comment

You should consider to include the full code of the component then, because the problem is not here
0

The reason that this.reqMak() is being called twice is subtle.

In your example you use an actual call to reqMak to delineate your function pointer for setTimeout(). The first time it is called is when you set up setTimeout; the second time is when setTimeout() runs, 2 seconds later.

The reason the suggested answer works is that it neither calls reqMak 'now', nor calls it later, as the function called by setTimeout(). What it does do is pass an anonymous function ()=>{} to setTimeout() for running later. And when setTimeout() runs the function, 2 seconds later, the anonymous function calls this.reqMak(), once.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.