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
Jared Palmer committed
Mar 18, 2019 at 14:22 UTC
2b93d686e359c7afa299e2ec5cf63160a32a1155
10 files changed
+96
-20
packages/react-debug-tools/src/__tests__/ReactHooksInspection-test.js
+6
-1
@@ -279,7 +279,12 @@ describe('ReactHooksInspection', () => {
279
expect(() => {
280
ReactDebugTools.inspectHooks(Foo, {}, FakeDispatcherRef);
281
}).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.',
288
);
289
290
expect(getterCalls).toBe(1);
packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js
+6
-1
@@ -657,7 +657,12 @@ describe('ReactHooksInspectionIntegration', () => {
657
expect(() => {
658
ReactDebugTools.inspectHooksOfFiber(childFiber, FakeDispatcherRef);
659
}).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.',
666
);
667
668
expect(getterCalls).toBe(1);
packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.internal.js
+12
-2
@@ -144,7 +144,12 @@ describe('ReactDOMServerHooks', () => {
144
145
return render(<Counter />);
146
},
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.',
153
);
154
155
itRenders('multiple times when an updater is called', async render => {
@@ -626,7 +631,12 @@ describe('ReactDOMServerHooks', () => {
631
632
return render(<Counter />);
633
},
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.',
640
);
641
});
642
packages/react-dom/src/server/ReactPartialRendererHooks.js
+6
-2
@@ -57,8 +57,12 @@ let currentHookNameInDev: ?string;
57
function resolveCurrentlyRenderingComponent(): Object {
58
invariant(
59
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.',
66
);
67
if (__DEV__) {
68
warning(
packages/react-reconciler/src/ReactFiberHooks.js
+6
-2
@@ -278,8 +278,12 @@ function warnOnHookMismatchInDev(currentHookName: HookType) {
278
function throwInvalidHookError() {
279
invariant(
280
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.',
287
);
288
}
289
packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+24
-4
@@ -46,7 +46,12 @@ describe('ReactHooks', () => {
46
expect(() => {
47
ReactTestRenderer.create(<Example />);
48
}).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.',
55
);
56
});
57
}
@@ -875,15 +880,30 @@ describe('ReactHooks', () => {
880
const root = ReactTestRenderer.create(<MemoApp />);
881
// trying to render again should trigger comparison and throw
882
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.',
889
);
890
// the next round, it does a fresh mount, so should render
891
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.',
898
);
899
// and then again, fail
900
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.',
907
);
908
});
909
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.internal.js
+18
-3
@@ -110,7 +110,12 @@ describe('ReactHooksWithNoopRenderer', () => {
110
ReactNoop.render(<BadCounter />);
111
112
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.',
119
);
120
121
// Confirm that a subsequent hook works properly.
@@ -133,7 +138,12 @@ describe('ReactHooksWithNoopRenderer', () => {
138
}
139
ReactNoop.render(<Counter />);
140
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.',
147
);
148
149
// Confirm that a subsequent hook works properly.
@@ -147,7 +157,12 @@ describe('ReactHooksWithNoopRenderer', () => {
157
158
it('throws when called outside the render phase', () => {
159
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.',
166
);
167
});
168
packages/react-reconciler/src/__tests__/ReactNewContext-test.internal.js
+6
-1
@@ -1517,7 +1517,12 @@ describe('ReactNewContext', () => {
1517
}
1518
ReactNoop.render(<Foo />);
1519
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.',
1526
);
1527
});
1528
packages/react-test-renderer/src/ReactShallowRenderer.js
+6
-2
@@ -218,8 +218,12 @@ class ReactShallowRenderer {
218
_validateCurrentlyRenderingComponent() {
219
invariant(
220
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.',
227
);
228
}
229
packages/react/src/ReactHooks.js
+6
-2
@@ -17,8 +17,12 @@ function resolveDispatcher() {
17
const dispatcher = ReactCurrentDispatcher.current;
18
invariant(
19
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.',
26
);
27
return dispatcher;
28
}