From b9a34155bf37298e99922f77dec8e27292db06d9 Mon Sep 17 00:00:00 2001 From: restrry Date: Wed, 15 Feb 2017 12:49:19 +0100 Subject: [PATCH] [fixed] compatibility with unstable_handleError in current React version componentWillUnmount could be called without calling componentDidMount if errors during rendering are handled via unstable_handleError method --- lib/components/Modal.js | 4 ++++ specs/Modal.spec.js | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/components/Modal.js b/lib/components/Modal.js index 2089f81e..0162fb98 100644 --- a/lib/components/Modal.js +++ b/lib/components/Modal.js @@ -86,6 +86,8 @@ export default class Modal extends Component { const parent = getParentElement(this.props.parentSelector); parent.appendChild(this.node); this.renderPortal(this.props); + + this.mounted = true; } componentWillReceiveProps (newProps) { @@ -101,6 +103,8 @@ export default class Modal extends Component { } componentWillUnmount () { + if (!this.mounted) return; + if (this.props.ariaHideApp) { ariaAppHider.show(this.props.appElement); } diff --git a/specs/Modal.spec.js b/specs/Modal.spec.js index 0427f408..574716ea 100644 --- a/specs/Modal.spec.js +++ b/specs/Modal.spec.js @@ -6,7 +6,7 @@ react/no-render-return-value: "warn" */ import TestUtils from 'react-addons-test-utils'; -import React from 'react'; +import React, { Component } from 'react'; import sinon from 'sinon'; import expect from 'expect'; import ReactDOM from 'react-dom'; @@ -519,4 +519,37 @@ describe('Modal', () => { done(); }, closeTimeoutMS); }); + + it('shouldn\'t throw if forcibly unmounted during mounting', () => { + /* eslint-disable camelcase, react/prop-types */ + class Wrapper extends Component { + constructor (props) { + super(props); + this.state = { error: false }; + } + unstable_handleError () { + this.setState({ error: true }); + } + render () { + return this.state.error ? null :
{ this.props.children }
; + } + } + /* eslint-enable camelcase, react/prop-types */ + + const Throw = () => { throw new Error('reason'); }; + const TestCase = () => ( + + + + + ); + + const currentDiv = document.createElement('div'); + document.body.appendChild(currentDiv); + + const mount = () => ReactDOM.render(, currentDiv); + expect(mount).toNotThrow(); + + document.body.removeChild(currentDiv); + }); });