From cb3036e3a2ef6f9215cd5273ded4603a1d9708e4 Mon Sep 17 00:00:00 2001 From: BaZzz01010101 Date: Mon, 25 Mar 2019 13:50:31 +0200 Subject: [PATCH 1/2] [Fix] Prevent outside click events for unmounted component --- src/OutsideClickHandler.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OutsideClickHandler.jsx b/src/OutsideClickHandler.jsx index 719ef57..d1b6bb9 100644 --- a/src/OutsideClickHandler.jsx +++ b/src/OutsideClickHandler.jsx @@ -37,9 +37,11 @@ export default class OutsideClickHandler extends React.Component { this.onMouseDown = this.onMouseDown.bind(this); this.onMouseUp = this.onMouseUp.bind(this); this.setChildNodeRef = this.setChildNodeRef.bind(this); + this._isMounted = false; } componentDidMount() { + this._isMounted = true; const { disabled, useCapture } = this.props; if (!disabled) this.addMouseDownEventListener(useCapture); @@ -57,6 +59,7 @@ export default class OutsideClickHandler extends React.Component { } componentWillUnmount() { + this._isMounted = false; this.removeEventListeners(); } @@ -87,7 +90,7 @@ export default class OutsideClickHandler extends React.Component { if (this.removeMouseUp) this.removeMouseUp(); this.removeMouseUp = null; - if (!isDescendantOfRoot) { + if (this._isMounted && !isDescendantOfRoot) { onOutsideClick(e); } } From 69e00707b357fe7faae595b923a17da6975737f0 Mon Sep 17 00:00:00 2001 From: BaZzz01010101 Date: Wed, 12 Jun 2019 16:17:45 +0300 Subject: [PATCH 2/2] Update regression test --- test/OutsideClickHandler_test.jsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/OutsideClickHandler_test.jsx b/test/OutsideClickHandler_test.jsx index 11b312c..46e24e3 100644 --- a/test/OutsideClickHandler_test.jsx +++ b/test/OutsideClickHandler_test.jsx @@ -40,6 +40,7 @@ describe('OutsideClickHandler', () => { const instance = wrapper.instance(); instance.childNode = {}; + instance._isMounted = true; target.parentNode = instance.childNode; expect(contains(instance.childNode, target)).to.equal(true); @@ -48,13 +49,28 @@ describe('OutsideClickHandler', () => { expect(spy).to.have.property('callCount', 0); }); - describe('when `this.childNode` does not contain `e.target`', () => { + it('is a noop if `this._isMounted` is `false`', () => { + const spy = sinon.spy(); + const wrapper = shallow(); + const instance = wrapper.instance(); + + instance.childNode = {}; + instance._isMounted = false; + expect(contains(instance.childNode, target)).to.equal(false); + + instance.onMouseUp(event); + + expect(spy).to.have.property('callCount', 0); + }); + + describe('when `this.childNode` does not contain `e.target` and `this._isMounted` is `true`', () => { it('calls onOutsideClick', () => { const spy = sinon.spy(); const wrapper = shallow(); const instance = wrapper.instance(); instance.childNode = {}; + instance._isMounted = true; expect(contains(instance.childNode, target)).to.equal(false); instance.onMouseUp(event); @@ -63,6 +79,7 @@ describe('OutsideClickHandler', () => { expect(spy.firstCall.args).to.eql([event]); }); }); + }); describe.skip('lifecycle methods', () => {