From 5149f1e62c34c5a6e426124bb9127a8924e5e96a Mon Sep 17 00:00:00 2001 From: Jared Palmer Date: Mon, 18 Mar 2019 09:55:27 -0400 Subject: [PATCH 1/4] Add more info to invalid hook call error message --- .../react-dom/src/server/ReactPartialRendererHooks.js | 8 ++++++-- packages/react-reconciler/src/ReactFiberHooks.js | 8 ++++++-- packages/react-test-renderer/src/ReactShallowRenderer.js | 8 ++++++-- packages/react/src/ReactHooks.js | 8 ++++++-- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/react-dom/src/server/ReactPartialRendererHooks.js b/packages/react-dom/src/server/ReactPartialRendererHooks.js index f1d2de025da45..f7df185b18a01 100644 --- a/packages/react-dom/src/server/ReactPartialRendererHooks.js +++ b/packages/react-dom/src/server/ReactPartialRendererHooks.js @@ -57,8 +57,12 @@ let currentHookNameInDev: ?string; function resolveCurrentlyRenderingComponent(): Object { invariant( currentlyRenderingComponent !== null, - 'Hooks can only be called inside the body of a function component. ' + - '(https://fb.me/react-invalid-hook-call)', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and React DOM\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for more information.', ); if (__DEV__) { warning( diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 655955072f40d..7832507baac98 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -278,8 +278,12 @@ function warnOnHookMismatchInDev(currentHookName: HookType) { function throwInvalidHookError() { invariant( false, - 'Hooks can only be called inside the body of a function component. ' + - '(https://fb.me/react-invalid-hook-call)', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and React DOM\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for more information.', ); } diff --git a/packages/react-test-renderer/src/ReactShallowRenderer.js b/packages/react-test-renderer/src/ReactShallowRenderer.js index 120fe54383ea0..de47d8ecf58d4 100644 --- a/packages/react-test-renderer/src/ReactShallowRenderer.js +++ b/packages/react-test-renderer/src/ReactShallowRenderer.js @@ -218,8 +218,12 @@ class ReactShallowRenderer { _validateCurrentlyRenderingComponent() { invariant( this._rendering && !this._instance, - 'Hooks can only be called inside the body of a function component. ' + - '(https://fb.me/react-invalid-hook-call)', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and React DOM\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for more information.', ); } diff --git a/packages/react/src/ReactHooks.js b/packages/react/src/ReactHooks.js index 784ab8fe31943..3c8297fb2d963 100644 --- a/packages/react/src/ReactHooks.js +++ b/packages/react/src/ReactHooks.js @@ -17,8 +17,12 @@ function resolveDispatcher() { const dispatcher = ReactCurrentDispatcher.current; invariant( dispatcher !== null, - 'Hooks can only be called inside the body of a function component. ' + - '(https://fb.me/react-invalid-hook-call)', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and React DOM\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for more information.', ); return dispatcher; } From d1a8abe94f7b5e918a3973dc6e701b183d35531d Mon Sep 17 00:00:00 2001 From: Jared Palmer Date: Mon, 18 Mar 2019 10:18:28 -0400 Subject: [PATCH 2/4] Update other renderers + change call to action --- packages/react-dom/src/server/ReactPartialRendererHooks.js | 4 ++-- packages/react-reconciler/src/ReactFiberHooks.js | 4 ++-- packages/react-test-renderer/src/ReactShallowRenderer.js | 4 ++-- packages/react/src/ReactHooks.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-dom/src/server/ReactPartialRendererHooks.js b/packages/react-dom/src/server/ReactPartialRendererHooks.js index f7df185b18a01..33c333cc79533 100644 --- a/packages/react-dom/src/server/ReactPartialRendererHooks.js +++ b/packages/react-dom/src/server/ReactPartialRendererHooks.js @@ -59,10 +59,10 @@ function resolveCurrentlyRenderingComponent(): Object { currentlyRenderingComponent !== null, 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + - '1. You might have mismatching versions of React and React DOM\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + - 'See https://fb.me/react-invalid-hook-call for more information.', + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); if (__DEV__) { warning( diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 7832507baac98..57d8a7c4edb71 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -280,10 +280,10 @@ function throwInvalidHookError() { false, 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + - '1. You might have mismatching versions of React and React DOM\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + - 'See https://fb.me/react-invalid-hook-call for more information.', + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); } diff --git a/packages/react-test-renderer/src/ReactShallowRenderer.js b/packages/react-test-renderer/src/ReactShallowRenderer.js index de47d8ecf58d4..850b2b37417b2 100644 --- a/packages/react-test-renderer/src/ReactShallowRenderer.js +++ b/packages/react-test-renderer/src/ReactShallowRenderer.js @@ -220,10 +220,10 @@ class ReactShallowRenderer { this._rendering && !this._instance, 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + - '1. You might have mismatching versions of React and React DOM\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + - 'See https://fb.me/react-invalid-hook-call for more information.', + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); } diff --git a/packages/react/src/ReactHooks.js b/packages/react/src/ReactHooks.js index 3c8297fb2d963..9c325b32a4321 100644 --- a/packages/react/src/ReactHooks.js +++ b/packages/react/src/ReactHooks.js @@ -19,10 +19,10 @@ function resolveDispatcher() { dispatcher !== null, 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + - '1. You might have mismatching versions of React and React DOM\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + - 'See https://fb.me/react-invalid-hook-call for more information.', + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); return dispatcher; } From 90770e2c7942f5b37b69c91526361fa8f8ed0dcf Mon Sep 17 00:00:00 2001 From: Jared Palmer Date: Mon, 18 Mar 2019 10:24:28 -0400 Subject: [PATCH 3/4] Update related tests for new hooks error message --- .../__tests__/ReactHooksInspection-test.js | 7 ++++- .../ReactHooksInspectionIntegration-test.js | 7 ++++- ...DOMServerIntegrationHooks-test.internal.js | 14 ++++++++-- .../src/__tests__/ReactHooks-test.internal.js | 28 ++++++++++++++++--- ...eactHooksWithNoopRenderer-test.internal.js | 21 ++++++++++++-- .../ReactNewContext-test.internal.js | 7 ++++- 6 files changed, 72 insertions(+), 12 deletions(-) diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.js index f5b57a531abaa..f1c54cdecbe19 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.js @@ -279,7 +279,12 @@ describe('ReactHooksInspection', () => { expect(() => { ReactDebugTools.inspectHooks(Foo, {}, FakeDispatcherRef); }).toThrow( - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); expect(getterCalls).toBe(1); diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js index c12270626b0a4..8faffa48e5f34 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js @@ -657,7 +657,12 @@ describe('ReactHooksInspectionIntegration', () => { expect(() => { ReactDebugTools.inspectHooksOfFiber(childFiber, FakeDispatcherRef); }).toThrow( - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); expect(getterCalls).toBe(1); diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.internal.js index f93c51b8385e3..a0a91763a82cf 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.internal.js @@ -144,7 +144,12 @@ describe('ReactDOMServerHooks', () => { return render(); }, - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); itRenders('multiple times when an updater is called', async render => { @@ -626,7 +631,12 @@ describe('ReactDOMServerHooks', () => { return render(); }, - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); }); diff --git a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js index b02561c2e7a98..4b13a21079ad2 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js @@ -46,7 +46,12 @@ describe('ReactHooks', () => { expect(() => { ReactTestRenderer.create(); }).toThrow( - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); }); } @@ -875,15 +880,30 @@ describe('ReactHooks', () => { const root = ReactTestRenderer.create(); // trying to render again should trigger comparison and throw expect(() => root.update()).toThrow( - 'Hooks can only be called inside the body of a function component', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); // the next round, it does a fresh mount, so should render expect(() => root.update()).not.toThrow( - 'Hooks can only be called inside the body of a function component', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); // and then again, fail expect(() => root.update()).toThrow( - 'Hooks can only be called inside the body of a function component', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); }); diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js index 8988181be26c3..6fd77a90e400c 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js @@ -110,7 +110,12 @@ describe('ReactHooksWithNoopRenderer', () => { ReactNoop.render(); expect(Scheduler).toFlushAndThrow( - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); // Confirm that a subsequent hook works properly. @@ -133,7 +138,12 @@ describe('ReactHooksWithNoopRenderer', () => { } ReactNoop.render(); expect(Scheduler).toFlushAndThrow( - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); // Confirm that a subsequent hook works properly. @@ -147,7 +157,12 @@ describe('ReactHooksWithNoopRenderer', () => { it('throws when called outside the render phase', () => { expect(() => useState(0)).toThrow( - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); }); diff --git a/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js b/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js index 8e57a6679293a..061852e87b621 100644 --- a/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js @@ -1517,7 +1517,12 @@ describe('ReactNewContext', () => { } ReactNoop.render(); expect(Scheduler).toFlushAndThrow( - 'Hooks can only be called inside the body of a function component.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + + ' one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); }); From 0f6a8ca4c92ae9f738d1b15f24caba4f7bd82a04 Mon Sep 17 00:00:00 2001 From: Jared Palmer Date: Mon, 18 Mar 2019 10:36:04 -0400 Subject: [PATCH 4/4] Fix lint errors --- .../src/__tests__/ReactHooks-test.internal.js | 4 ++-- .../src/__tests__/ReactNewContext-test.internal.js | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js index 4b13a21079ad2..8933125cbfdc9 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js @@ -46,8 +46,8 @@ describe('ReactHooks', () => { expect(() => { ReactTestRenderer.create(); }).toThrow( - 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + - ' one of the following reasons:\n' + + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen' + + ' for one of the following reasons:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + diff --git a/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js b/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js index 061852e87b621..e04b75dc593a1 100644 --- a/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js @@ -1517,12 +1517,12 @@ describe('ReactNewContext', () => { } ReactNoop.render(); expect(Scheduler).toFlushAndThrow( - 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + - ' one of the following reasons:\n' + - '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + - '2. You might be breaking the Rules of Hooks\n' + - '3. You might have more than one copy of React in the same app\n' + - 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', + 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen' + + ' for one of the following reasons:\n' + + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + + '2. You might be breaking the Rules of Hooks\n' + + '3. You might have more than one copy of React in the same app\n' + + 'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.', ); });