2015-04-08 10 views
8

C'è un modo per uccidere/(eliminare) un timeout in reactjs?interrompendo un timeout in reactjs?

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

Su una specie di clic o azione, voglio essere in grado di fermarsi completamente e terminare il timeout. C'è un modo per fare questo? Grazie.

+4

è ancora solo JS, lo fai nello stesso modo in cui lo faresti senza React. –

+0

'clearTimeout' funzionerà assumendo che tu memorizzi l'id del timer. – WiredPrairie

risposta

9

si dovrebbe usare 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; 

... e nel componente:

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

Maggiori informazioni: https://facebook.github.io/react/docs/reusable-components.html

+11

Come si tradurrebbe in React usando le classi ES6? I mixin sono presto deprecati – Scotty

+0

Per chiunque si stia chiedendo la stessa cosa di @Scotty, ho inviato una versione 2017 della risposta appena sotto .. – jmgem

+0

non è più aggiornato – tatsu

8

Supponendo che questo stia accadendo all'interno di un componente, memorizzare l'id di timeout in modo che possa essere cancellato in seguito. Altrimenti, dovrai archiviare l'ID da qualche altra parte a cui è possibile accedere successivamente, come un oggetto negozio esterno.

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

// ...elsewhere... 

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

Probabilmente si vorrà anche assicurarsi qualsiasi timeout in attesa viene cancellato in componentWillUnmount() troppo:

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

Se avete un po 'interfaccia utente, che dipende dal fatto o meno un timeout è in attesa, è' Voglio invece archiviare l'id nello stato del componente appropriato.

+0

C'è un errore di sintassi nel primo snippet di codice, dovrebbe essere - 'setTimeout (function() {' invece di 'setTimeout (function(), {' – Atty

7

Dal Reagire mixins ora sono deprecati, ecco un esempio di un componente di ordine superiore che racchiude un altro componente per fornire la stessa funzionalità descritta nella risposta accettata. Pulisce ordinatamente qualsiasi timeout rimanente su unmount e fornisce al componente figlio un'API per gestirlo tramite oggetti di scena.

Questo utilizza classi ES6 e component composition che è il metodo consigliato per sostituire mixins nel 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

Questo è fantastico! Come passeresti? MyComponent to Timeout se stai usando la funzione 'connect' di Redux? –