From 0922176bb5b6f807f9ece6e6ee2b4af45f8b427d Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Tue, 14 Apr 2015 22:54:42 -0400 Subject: [PATCH] Clear initial resetTriggers timeout on unmount If the Resizable component is unmounted before the initial resetTriggers timeout fires, an exception will be thrown when resetTriggers attempts to read from the DOM. Store a reference to the resetTriggers timeout ID and clear it before the component unmounts. --- karma.conf.js | 32 ++++++++++++++++++++++++++++++++ package.json | 13 +++++++++++-- src/component.js | 7 ++++++- test/ResizeableTest.js | 28 ++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 karma.conf.js create mode 100644 test/ResizeableTest.js diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..d93c52e --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,32 @@ +module.exports = function (config) { + config.set({ + frameworks: [ + 'mocha', + 'chai', + 'sinon', + 'browserify' + ], + + files: [ + 'test/**/*.js' + ], + + browserify: { + debug: true + }, + + preprocessors: { + 'test/**/*.js': ['browserify'] + }, + + reporters: ['progress'], + + browsers: ['Chrome'], + + client: { + mocha: { + reporter: 'html' + } + } + }); +}; diff --git a/package.json b/package.json index 7fe8ac2..66a79c8 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "React component to react on resize event using scroll trick", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "karma start --single-run" }, "repository": { "type": "git", @@ -23,7 +23,16 @@ "object-assign": "^1.0.0" }, "devDependencies": { - "react": "^0.12.0" + "chai": "^2.2.0", + "karma": "^0.12.31", + "karma-browserify": "^4.1.2", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^0.1.7", + "karma-mocha": "^0.1.10", + "karma-sinon": "^1.0.4", + "mocha": "^2.2.4", + "react": "^0.12.0", + "sinon": "^1.14.1" }, "peerDependencies": { "react": "^0.12.0" diff --git a/src/component.js b/src/component.js index 5c4a790..bb01862 100644 --- a/src/component.js +++ b/src/component.js @@ -32,8 +32,13 @@ var Resizeable = React.createClass({ componentDidMount: function () { this.resetTriggers(); - setTimeout(this.resetTriggers, 1000); + this.initialResetTriggersTimeout = setTimeout(this.resetTriggers, 1000); }, + + componentWillUnmount: function () { + clearTimeout(this.initialResetTriggersTimeout); + }, + componentDidUpdate: function () { this.resetTriggers(); }, diff --git a/test/ResizeableTest.js b/test/ResizeableTest.js new file mode 100644 index 0000000..b49840e --- /dev/null +++ b/test/ResizeableTest.js @@ -0,0 +1,28 @@ +var React = require('react/addons'); +var Resizeable = require('../src/component'); +var ReactTestUtils = require('react/lib/ReactTestUtils'); + +describe('Resizeable', function () { + + it('should mount', function () { + var root = ReactTestUtils.renderIntoDocument(React.createElement(Resizeable, { + onResize: function () {} + })); + + root.should.exist; + }); + + it('should clean up timeouts on unmount', function () { + var clock = sinon.useFakeTimers(); + var container = document.createElement('div'); + + React.render(React.createElement(Resizeable, { + onResize: function () {} + }), container); + + React.unmountComponentAtNode(container); + + clock.tick(1000); + clock.restore(); + }); +});