Skip to content
This repository has been archived by the owner on Jun 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #227 from carpie/clear_snackbar_timer_on_unmount
Browse files Browse the repository at this point in the history
Clear snackbar timeout timer on unmount (fix for #226)
  • Loading branch information
tleunen committed Feb 22, 2016
2 parents bb83515 + 81baa08 commit ce83049
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
15 changes: 14 additions & 1 deletion src/Snackbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class Snackbar extends React.Component {
super(props);
this.clearTimer = this.clearTimer.bind(this);
this.timeoutId = null;
this.clearTimeoutId = null;
this.state = {
open: false
};
Expand All @@ -48,11 +49,23 @@ class Snackbar extends React.Component {
}
}

componentWillUnmount() {
if(this.timeoutId) {
clearTimeout(this.timeoutId);
this.timeoutId = null;
}
if(this.clearTimeoutId) {
clearTimeout(this.clearTimeoutId);
this.clearTimeoutId = null;
}
}

clearTimer() {
this.timeoutId = null;
this.setState({ open: false });

setTimeout(() => {
this.clearTimeoutId = setTimeout(() => {
this.clearTimeoutId = null;
this.props.onTimeout();
}, ANIMATION_LENGTH);
}
Expand Down
45 changes: 44 additions & 1 deletion src/__tests__/Snackbar-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import expect from 'expect';
import React from 'react';
import ReactDOM from 'react-dom';
import { Simulate } from 'react-addons-test-utils';
import { Simulate, renderIntoDocument } from 'react-addons-test-utils';
import { render, renderDOM } from './render';
import Snackbar from '../Snackbar';

Expand Down Expand Up @@ -79,4 +79,47 @@ describe('Snackbar', () => {
expect(el.querySelector('.mdl-snackbar__action')).toNotBe(null);
Simulate.click(el.querySelector('.mdl-snackbar__action'));
});

it('should clear timeout timer when unmounted', (done) => {
const el = renderDOM(<Snackbar active={false} onTimeout={noop} />);
let pass = true;
function timeoutHandler() {
pass = false;
}
ReactDOM.render(<Snackbar active timeout={1} onTimeout={timeoutHandler} />, el.parentNode, () => {
// Force unmount
ReactDOM.unmountComponentAtNode(el.parentNode);
// Call done if the handler wasn't called
setTimeout(() => {
if (pass) {
done();
}
else {
throw new Error('onTimeout handler should not have been called because component was unmounted');
}
}, 300);
});
});

it('should clear the cleartimer timer when unmounted', (done) => {
let pass = true;
function timeoutHandler() {
pass = false;
}
const component = renderIntoDocument(<Snackbar active={false} timeout={1} onTimeout={timeoutHandler} />);
const el = ReactDOM.findDOMNode(component);
// The clearTimer animation period is a very small window, so we invoke clearTimer here directly to start it
component.clearTimer();
// Force unmount
ReactDOM.unmountComponentAtNode(el.parentNode);
// Call done if the handler wasn't called
setTimeout(() => {
if (pass) {
done();
}
else {
throw new Error('onTimeout handler should not have been called because component was unmounted');
}
}, 300);
});
});

0 comments on commit ce83049

Please sign in to comment.