33

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.

Simone Poggi
  • 1,448
  • 2
  • 15
  • 34
Rafael Mora
  • 1,095
  • 2
  • 13
  • 21

3 Answers3

63

Try this:

if (timerid) {
  clearTimeout(timerid);
}

timerid = setTimeout(() => {
  this.reqMaq(obj['fkmaqid'])
}, 2000);
Mehdi Namvar
  • 1,093
  • 8
  • 8
  • I had to declare a var in the `state` and then use it in the method where the `setTimeout()` resides – Rafael Mora Aug 17 '16 at 01:51
  • 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 https://stackoverflow.com/questions/23123138/perform-debounce-in-react-js – Simone Poggi Jul 25 '17 at 08:27
3

This should do the trick

const fx = () => this.reqMaq( obj['fkmaqid'] )
timerid = setTimeout( fx, 2000 )
Simone Poggi
  • 1,448
  • 2
  • 15
  • 34
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.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135