web-dev-qa-db-fra.com

arrêter un timeout dans reactjs?

Existe-t-il un moyen de tuer/(se débarrasser) d'un délai d'expiration dans reactjs?

setTimeout(function() {
//do something
}.bind(this), 3000);

Après une sorte de clic ou d'action, je veux pouvoir arrêter complètement et terminer le délai d'expiration. Y a-t-il un moyen de faire cela? Merci.

18
BlueElixir

Vous devez utiliser des mixins:

// file: mixins/settimeout.js:

var SetTimeoutMixin = {
    componentWillMount: function() {
        this.timeouts = [];
    },
    setTimeout: function() {
        this.timeouts.Push(setTimeout.apply(null, arguments));
    },

    clearTimeouts: function() {
        this.timeouts.forEach(clearTimeout);
    },

    componentWillUnmount: function() {
        this.clearTimeouts();
    }
};

export default SetTimeoutMixin;

... et dans votre composant:

// sampleComponent.js:
import SetTimeoutMixin from 'mixins/settimeout'; 

var SampleComponent = React.createClass({

    //mixins:
    mixins: [SetTimeoutMixin],

    // sample usage
    componentWillReceiveProps: function(newProps) {
        if (newProps.myValue != this.props.myValue) {
            this.clearTimeouts();
            this.setTimeout(function(){ console.log('do something'); }, 2000);
        }
    },
}

export default SampleComponent;

Plus d'informations: https://facebook.github.io/react/docs/reusable-components.html

10
Tomasz Szuba

En supposant que cela se produit à l'intérieur d'un composant, stockez l'ID de délai d'expiration afin qu'il puisse être annulé plus tard. Sinon, vous devrez stocker l'identifiant ailleurs où vous pourrez y accéder ultérieurement, comme un objet de stockage externe.

this.timeout = setTimeout(function() {
  // Do something
  this.timeout = null
}.bind(this), 3000)

// ...elsewhere...

if (this.timeout) {
  clearTimeout(this.timeout)
  this.timeout = null
}

Vous voudrez probablement également vous assurer que tout délai d'attente en attente est également annulé dans componentWillUnmount():

componentWillUnmount: function() {
  if (this.timeout) {
    clearTimeout(this.timeout)
  }
}

Si vous avez une interface utilisateur qui dépend si un délai d'attente est en attente ou non, vous voudrez plutôt stocker l'ID dans l'état du composant approprié.

22
Jonny Buchanan

Étant donné que React mixins sont désormais obsolètes, voici un exemple d'un composant d'ordre supérieur qui encapsule un autre composant pour donner les mêmes fonctionnalités que celles décrites dans la réponse acceptée. Il nettoie soigneusement tous les délais d'attente restants lors du démontage, et donne au composant enfant une API pour gérer cela via des accessoires.

Il utilise les classes ES6 et composition des composants qui est le moyen recommandé pour remplacer les mixins en 2017.

Dans Timeout.jsx

import React, { Component } from 'react';

const Timeout = Composition => class _Timeout extends Component {
    constructor(props) {
      super(props);
    }

    componentWillMount () {
      this.timeouts = [];
    }

    setTimeout () {
      this.timeouts.Push(setTimeout.apply(null, arguments));
    }

    clearTimeouts () {
      this.timeouts.forEach(clearTimeout);
    }

    componentWillUnmount () {
      this.clearTimeouts();
    }

    render () {
      const { timeouts, setTimeout, clearTimeouts } = this;

      return <Composition 
        timeouts={timeouts} 
        setTimeout={setTimeout} 
        clearTimeouts={clearTimeouts} 
        { ...this.props } />
    }
}

export default Timeout;

Dans MyComponent.jsx

import React, { Component } from 'react';
import Timeout from './Timeout';    

class MyComponent extends Component {
  constructor(props) {
    super(props)
  }

  componentDidMount () {
    // You can access methods of Timeout as they
    // were passed down as props.
    this.props.setTimeout(() => {
      console.log("Hey! I'm timing out!")
    }, 1000)
  }

  render () {
    return <span>Hello, world!</span>
  }
}

// Pass your component to Timeout to create the magic.
export default Timeout(MyComponent);
11
jmgem

J'ai arrêté un setTimeout dans mon application React avec Javascript uniquement:

(Mon cas d'utilisation consistait à enregistrer automatiquement uniquement après 3 secondes sans aucune frappe)

timeout;

handleUpdate(input:any) {
    this.setState({ title: input.value }, () => {

        clearTimeout(this.timeout);
        this.timeout = setTimeout(() => this.saveChanges(), 3000);

    });
}
1
Ben Cochrane