Skip to content

Commit 96a04bb

Browse files
committed
Fixes umount setState error. closes #4
1 parent 267c163 commit 96a04bb

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import sinon from 'sinon';
3+
import { mount } from 'enzyme';
4+
5+
import createAsyncComponent from '../createAsyncComponent';
6+
7+
describe('createAsyncComponent', () => {
8+
it('should handle unmounting ensuring that resolved promises do not call setState', () => {
9+
const resolveDelay = 10;
10+
const Bob = createAsyncComponent({
11+
resolve: () => new Promise(resolve =>
12+
setTimeout(
13+
() => resolve(() => <div>bob</div>),
14+
resolveDelay,
15+
),
16+
),
17+
});
18+
const setStateSpy = sinon.spy(Bob.prototype, 'setState');
19+
const renderWrapper = mount(<Bob />);
20+
expect(setStateSpy.callCount).toEqual(0);
21+
renderWrapper.unmount();
22+
return new Promise(resolve => setTimeout(resolve, resolveDelay + 2))
23+
.then(() => expect(setStateSpy.callCount).toEqual(0));
24+
});
25+
});

src/createAsyncComponent.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,19 @@ function createAsyncComponent(args) {
6363
}
6464

6565
resolveComponent() {
66-
return getResolver().then(Component =>
66+
return getResolver().then((Component) => {
67+
if (this.unmounted) {
68+
// The component is unmounted, so no need to set the state.
69+
return;
70+
}
6771
this.setState({
6872
Component: es6Resolve(Component),
69-
}),
70-
);
73+
});
74+
});
75+
}
76+
77+
componentWillUnmount() {
78+
this.unmounted = true;
7179
}
7280

7381
render() {

0 commit comments

Comments
 (0)