[Fast Refresh] Fix for intentional unmounts after an error (#17368)

This commit is contained in:
Ricky
2019-11-14 18:40:25 +00:00
committed by GitHub
parent df8db4e005
commit 769dd522a2
2 changed files with 40 additions and 0 deletions

View File

@@ -468,6 +468,10 @@ export function injectIntoGlobalHook(globalObject: any): void {
// TODO: Maybe we could fix this as the same time as when we fix
// DevTools to not depend on `alternate.memoizedState.element`.
didSomeRootFailOnMount = true;
} else if (!didError && failedRoots.has(root)) {
// The error is fixed but the component is still unmounted.
// This means that the unmount was not caused by a failed refresh.
failedRoots.delete(root);
}
}
} else {

View File

@@ -2870,6 +2870,42 @@ describe('ReactFresh', () => {
});
expect(container.innerHTML).toBe('');
expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
// Mount a new container.
render(() => {
function Hello() {
return <h1>Hi</h1>;
}
$RefreshReg$(Hello, 'Hello');
return Hello;
});
expect(container.innerHTML).toBe('<h1>Hi</h1>');
expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
// Break again.
expect(() => {
patch(() => {
function Hello() {
throw new Error('Oops');
}
$RefreshReg$(Hello, 'Hello');
});
}).toThrow('Oops');
expect(container.innerHTML).toBe('');
expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
// Check we don't attempt to reverse an intentional unmount, even after an error.
ReactDOM.unmountComponentAtNode(container);
expect(container.innerHTML).toBe('');
patch(() => {
function Hello() {
return <h1>Never mind me!</h1>;
}
$RefreshReg$(Hello, 'Hello');
});
expect(container.innerHTML).toBe('');
expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
}
});