Skip to content

Commit 2b93d68

Browse files
jaredpalmergaearon
authored andcommitted
Add more info to invalid hook call error message (#15139)
* Add more info to invalid hook call error message * Update other renderers + change call to action * Update related tests for new hooks error message * Fix lint errors
1 parent d926936 commit 2b93d68

10 files changed

+96
-20
lines changed

packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,12 @@ describe('ReactHooksInspection', () => {
279279
expect(() => {
280280
ReactDebugTools.inspectHooks(Foo, {}, FakeDispatcherRef);
281281
}).toThrow(
282-
'Hooks can only be called inside the body of a function component.',
282+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
283+
' one of the following reasons:\n' +
284+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
285+
'2. You might be breaking the Rules of Hooks\n' +
286+
'3. You might have more than one copy of React in the same app\n' +
287+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
283288
);
284289

285290
expect(getterCalls).toBe(1);

packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,12 @@ describe('ReactHooksInspectionIntegration', () => {
657657
expect(() => {
658658
ReactDebugTools.inspectHooksOfFiber(childFiber, FakeDispatcherRef);
659659
}).toThrow(
660-
'Hooks can only be called inside the body of a function component.',
660+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
661+
' one of the following reasons:\n' +
662+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
663+
'2. You might be breaking the Rules of Hooks\n' +
664+
'3. You might have more than one copy of React in the same app\n' +
665+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
661666
);
662667

663668
expect(getterCalls).toBe(1);

packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.internal.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,12 @@ describe('ReactDOMServerHooks', () => {
144144

145145
return render(<Counter />);
146146
},
147-
'Hooks can only be called inside the body of a function component.',
147+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
148+
' one of the following reasons:\n' +
149+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
150+
'2. You might be breaking the Rules of Hooks\n' +
151+
'3. You might have more than one copy of React in the same app\n' +
152+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
148153
);
149154

150155
itRenders('multiple times when an updater is called', async render => {
@@ -626,7 +631,12 @@ describe('ReactDOMServerHooks', () => {
626631

627632
return render(<Counter />);
628633
},
629-
'Hooks can only be called inside the body of a function component.',
634+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
635+
' one of the following reasons:\n' +
636+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
637+
'2. You might be breaking the Rules of Hooks\n' +
638+
'3. You might have more than one copy of React in the same app\n' +
639+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
630640
);
631641
});
632642

packages/react-dom/src/server/ReactPartialRendererHooks.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,12 @@ let currentHookNameInDev: ?string;
5757
function resolveCurrentlyRenderingComponent(): Object {
5858
invariant(
5959
currentlyRenderingComponent !== null,
60-
'Hooks can only be called inside the body of a function component. ' +
61-
'(https://fb.me/react-invalid-hook-call)',
60+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
61+
' one of the following reasons:\n' +
62+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
63+
'2. You might be breaking the Rules of Hooks\n' +
64+
'3. You might have more than one copy of React in the same app\n' +
65+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
6266
);
6367
if (__DEV__) {
6468
warning(

packages/react-reconciler/src/ReactFiberHooks.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,12 @@ function warnOnHookMismatchInDev(currentHookName: HookType) {
278278
function throwInvalidHookError() {
279279
invariant(
280280
false,
281-
'Hooks can only be called inside the body of a function component. ' +
282-
'(https://fb.me/react-invalid-hook-call)',
281+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
282+
' one of the following reasons:\n' +
283+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
284+
'2. You might be breaking the Rules of Hooks\n' +
285+
'3. You might have more than one copy of React in the same app\n' +
286+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
283287
);
284288
}
285289

packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js

+24-4
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ describe('ReactHooks', () => {
4646
expect(() => {
4747
ReactTestRenderer.create(<Example />);
4848
}).toThrow(
49-
'Hooks can only be called inside the body of a function component.',
49+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen' +
50+
' for one of the following reasons:\n' +
51+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
52+
'2. You might be breaking the Rules of Hooks\n' +
53+
'3. You might have more than one copy of React in the same app\n' +
54+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
5055
);
5156
});
5257
}
@@ -875,15 +880,30 @@ describe('ReactHooks', () => {
875880
const root = ReactTestRenderer.create(<MemoApp />);
876881
// trying to render again should trigger comparison and throw
877882
expect(() => root.update(<MemoApp />)).toThrow(
878-
'Hooks can only be called inside the body of a function component',
883+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
884+
' one of the following reasons:\n' +
885+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
886+
'2. You might be breaking the Rules of Hooks\n' +
887+
'3. You might have more than one copy of React in the same app\n' +
888+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
879889
);
880890
// the next round, it does a fresh mount, so should render
881891
expect(() => root.update(<MemoApp />)).not.toThrow(
882-
'Hooks can only be called inside the body of a function component',
892+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
893+
' one of the following reasons:\n' +
894+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
895+
'2. You might be breaking the Rules of Hooks\n' +
896+
'3. You might have more than one copy of React in the same app\n' +
897+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
883898
);
884899
// and then again, fail
885900
expect(() => root.update(<MemoApp />)).toThrow(
886-
'Hooks can only be called inside the body of a function component',
901+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
902+
' one of the following reasons:\n' +
903+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
904+
'2. You might be breaking the Rules of Hooks\n' +
905+
'3. You might have more than one copy of React in the same app\n' +
906+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
887907
);
888908
});
889909

packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js

+18-3
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,12 @@ describe('ReactHooksWithNoopRenderer', () => {
110110
ReactNoop.render(<BadCounter />);
111111

112112
expect(Scheduler).toFlushAndThrow(
113-
'Hooks can only be called inside the body of a function component.',
113+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
114+
' one of the following reasons:\n' +
115+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
116+
'2. You might be breaking the Rules of Hooks\n' +
117+
'3. You might have more than one copy of React in the same app\n' +
118+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
114119
);
115120

116121
// Confirm that a subsequent hook works properly.
@@ -133,7 +138,12 @@ describe('ReactHooksWithNoopRenderer', () => {
133138
}
134139
ReactNoop.render(<Counter />);
135140
expect(Scheduler).toFlushAndThrow(
136-
'Hooks can only be called inside the body of a function component.',
141+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
142+
' one of the following reasons:\n' +
143+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
144+
'2. You might be breaking the Rules of Hooks\n' +
145+
'3. You might have more than one copy of React in the same app\n' +
146+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
137147
);
138148

139149
// Confirm that a subsequent hook works properly.
@@ -147,7 +157,12 @@ describe('ReactHooksWithNoopRenderer', () => {
147157

148158
it('throws when called outside the render phase', () => {
149159
expect(() => useState(0)).toThrow(
150-
'Hooks can only be called inside the body of a function component.',
160+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
161+
' one of the following reasons:\n' +
162+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
163+
'2. You might be breaking the Rules of Hooks\n' +
164+
'3. You might have more than one copy of React in the same app\n' +
165+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
151166
);
152167
});
153168

packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,12 @@ describe('ReactNewContext', () => {
15171517
}
15181518
ReactNoop.render(<Foo />);
15191519
expect(Scheduler).toFlushAndThrow(
1520-
'Hooks can only be called inside the body of a function component.',
1520+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen' +
1521+
' for one of the following reasons:\n' +
1522+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
1523+
'2. You might be breaking the Rules of Hooks\n' +
1524+
'3. You might have more than one copy of React in the same app\n' +
1525+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
15211526
);
15221527
});
15231528

packages/react-test-renderer/src/ReactShallowRenderer.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,12 @@ class ReactShallowRenderer {
218218
_validateCurrentlyRenderingComponent() {
219219
invariant(
220220
this._rendering && !this._instance,
221-
'Hooks can only be called inside the body of a function component. ' +
222-
'(https://fb.me/react-invalid-hook-call)',
221+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
222+
' one of the following reasons:\n' +
223+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
224+
'2. You might be breaking the Rules of Hooks\n' +
225+
'3. You might have more than one copy of React in the same app\n' +
226+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
223227
);
224228
}
225229

packages/react/src/ReactHooks.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ function resolveDispatcher() {
1717
const dispatcher = ReactCurrentDispatcher.current;
1818
invariant(
1919
dispatcher !== null,
20-
'Hooks can only be called inside the body of a function component. ' +
21-
'(https://fb.me/react-invalid-hook-call)',
20+
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
21+
' one of the following reasons:\n' +
22+
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
23+
'2. You might be breaking the Rules of Hooks\n' +
24+
'3. You might have more than one copy of React in the same app\n' +
25+
'See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.',
2226
);
2327
return dispatcher;
2428
}

0 commit comments

Comments
 (0)