2015-04-08 7 views
8

Gibt es eine Möglichkeit, ein Timeout in reactjs zu töten/(loswerden)?ein Timeout in reactjs stoppen?

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

Nach einer Art von Klick oder Aktion möchte ich in der Lage sein, die Zeitüberschreitung vollständig zu stoppen und zu beenden. Gibt es eine Möglichkeit, dies zu tun? Vielen Dank.

+4

zu ersetzen es ist immer noch nur JS, du machst es genauso wie du es ohne React machen würdest. –

+0

'clearTimeout' funktioniert, wenn Sie die Timer-ID speichern. – WiredPrairie

Antwort

9

sollten Sie verwenden 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; 

... und in der Komponente:

// 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; 

Weitere Informationen: https://facebook.github.io/react/docs/reusable-components.html

+11

Wie würde dies zu React mit ES6-Klassen? Mixins werden bald veraltet – Scotty

+0

Für alle, die dasselbe wie @Scotty fragen, habe ich eine 2017 Version der Antwort hier unten eingereicht: – jmgem

+0

Dies ist nicht mehr auf dem neuesten Stand. – tatsu

8

Angenommen, dies geschieht in einer Komponente, speichern Sie die Timeout-ID, damit sie später abgebrochen werden kann. Andernfalls müssen Sie die ID an einem anderen Ort speichern, auf den später zugegriffen werden kann, z. B. ein externes Speicherobjekt.

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

// ...elsewhere... 

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

Sie werden wahrscheinlich sicher machen möchte auch eine anstehende Timeout auch in componentWillUnmount() abgesagt wird:

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

Wenn Sie einige UI haben die davon abhängt, ob ein Timeout ansteht, Sie‘ Ich möchte die ID stattdessen im entsprechenden Komponentenstatus speichern.

+0

Es gibt einen Syntaxfehler im ersten Code-Snippet, sollte sein - 'setTimeout (function() {' anstelle von 'setTimeout (function(), {' – Atty

7

Seit React Mixins jetzt veraltet sind, hier ist ein Beispiel für eine Komponente höherer Ordnung, die eine andere Komponente umschließt, um die gleiche Funktionalität wie in der akzeptierten Antwort beschrieben zu erhalten. Es räumt sauber alle verbleibenden Timeouts beim Unmounten auf und gibt der untergeordneten Komponente eine API, um diese über Requisiten zu verwalten.

Dies verwendet ES6 Klassen und component composition, welche die empfohlene Methode ist Mixins in 2017.

In 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; 

In 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); 
+0

Wicked! Cheers @jmgem! – Scotty

+0

Das ist großartig! Wie würdest du gehen MyComponent zu Timeout, wenn Sie die 'connect'-Funktion von redux verwenden? –