Skip to content

Commit b9a3415

Browse files
committed
[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
1 parent ba2fe90 commit b9a3415

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

lib/components/Modal.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ export default class Modal extends Component {
8686
const parent = getParentElement(this.props.parentSelector);
8787
parent.appendChild(this.node);
8888
this.renderPortal(this.props);
89+
90+
this.mounted = true;
8991
}
9092

9193
componentWillReceiveProps (newProps) {
@@ -101,6 +103,8 @@ export default class Modal extends Component {
101103
}
102104

103105
componentWillUnmount () {
106+
if (!this.mounted) return;
107+
104108
if (this.props.ariaHideApp) {
105109
ariaAppHider.show(this.props.appElement);
106110
}

specs/Modal.spec.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
react/no-render-return-value: "warn"
77
*/
88
import TestUtils from 'react-addons-test-utils';
9-
import React from 'react';
9+
import React, { Component } from 'react';
1010
import sinon from 'sinon';
1111
import expect from 'expect';
1212
import ReactDOM from 'react-dom';
@@ -519,4 +519,37 @@ describe('Modal', () => {
519519
done();
520520
}, closeTimeoutMS);
521521
});
522+
523+
it('shouldn\'t throw if forcibly unmounted during mounting', () => {
524+
/* eslint-disable camelcase, react/prop-types */
525+
class Wrapper extends Component {
526+
constructor (props) {
527+
super(props);
528+
this.state = { error: false };
529+
}
530+
unstable_handleError () {
531+
this.setState({ error: true });
532+
}
533+
render () {
534+
return this.state.error ? null : <div>{ this.props.children }</div>;
535+
}
536+
}
537+
/* eslint-enable camelcase, react/prop-types */
538+
539+
const Throw = () => { throw new Error('reason'); };
540+
const TestCase = () => (
541+
<Wrapper>
542+
<Modal />
543+
<Throw />
544+
</Wrapper>
545+
);
546+
547+
const currentDiv = document.createElement('div');
548+
document.body.appendChild(currentDiv);
549+
550+
const mount = () => ReactDOM.render(<TestCase />, currentDiv);
551+
expect(mount).toNotThrow();
552+
553+
document.body.removeChild(currentDiv);
554+
});
522555
});

0 commit comments

Comments
 (0)