Stop timeout in reactions?

Is there a way I can kill / (get rid of) a timeout in a reaction?

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

After some click or action, I want to completely stop and complete the timeout. Is there any way to do this? thanks.

+8
reactjs settimeout
source share
3 answers

You should use 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; 

... and in your component:

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

Additional information: https://facebook.imtqy.com/react/docs/reusable-components.html

+9
source share

Assuming this happens inside the component, save the timeout identifier so that it can be undone later. Otherwise, you will need to save the identifier in another place, which it can access later, for example, an external storage object.

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

You probably also want any pending timeout also to be canceled in componentWillUnmount() :

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

If you have some user interface, which depends on whether the delayed timeout expects, you will want to save the identifier in the corresponding state of the component.

+8
source share

Since React mixins are now deprecated, here is an example of a higher order component that wraps another component to give the same functions as described in the accepted answer. It gently cleans up any remaining timeouts on shutdown and provides the child component with an API to manage this through the details.

This uses ES6 classes and component composition , which is the recommended way to replace 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); 
+7
source share

All Articles