@samitouri / QOS-React / commits / 769dd522a2

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

Ricky committed Nov 14, 2019 at 18:40 UTC 769dd522a2f6843f7e22d903fce296cb9faab88b
2 files changed +40
packages/react-refresh/src/ReactFreshRuntime.js
+4
@@ -468,6 +468,10 @@ export function injectIntoGlobalHook(globalObject: any): void {
468 // TODO: Maybe we could fix this as the same time as when we fix
469 // DevTools to not depend on `alternate.memoizedState.element`.
470 didSomeRootFailOnMount = true;
471 + } else if (!didError && failedRoots.has(root)) {
472 + // The error is fixed but the component is still unmounted.
473 + // This means that the unmount was not caused by a failed refresh.
474 + failedRoots.delete(root);
475 }
476 }
477 } else {
packages/react-refresh/src/__tests__/ReactFresh-test.js
+36
@@ -2870,6 +2870,42 @@ describe('ReactFresh', () => {
2870 });
2871 expect(container.innerHTML).toBe('');
2872 expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
2873 +
2874 + // Mount a new container.
2875 + render(() => {
2876 + function Hello() {
2877 + return <h1>Hi</h1>;
2878 + }
2879 + $RefreshReg$(Hello, 'Hello');
2880 +
2881 + return Hello;
2882 + });
2883 + expect(container.innerHTML).toBe('<h1>Hi</h1>');
2884 + expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
2885 +
2886 + // Break again.
2887 + expect(() => {
2888 + patch(() => {
2889 + function Hello() {
2890 + throw new Error('Oops');
2891 + }
2892 + $RefreshReg$(Hello, 'Hello');
2893 + });
2894 + }).toThrow('Oops');
2895 + expect(container.innerHTML).toBe('');
2896 + expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
2897 +
2898 + // Check we don't attempt to reverse an intentional unmount, even after an error.
2899 + ReactDOM.unmountComponentAtNode(container);
2900 + expect(container.innerHTML).toBe('');
2901 + patch(() => {
2902 + function Hello() {
2903 + return <h1>Never mind me!</h1>;
2904 + }
2905 + $RefreshReg$(Hello, 'Hello');
2906 + });
2907 + expect(container.innerHTML).toBe('');
2908 + expect(ReactFreshRuntime.hasUnrecoverableErrors()).toBe(false);
2909 }
2910 });
2911