diff --git a/packages/react-dom/src/server/ReactPartialRendererHooks.js b/packages/react-dom/src/server/ReactPartialRendererHooks.js
index b9ec4e118a73..f1d2de025da4 100644
--- a/packages/react-dom/src/server/ReactPartialRendererHooks.js
+++ b/packages/react-dom/src/server/ReactPartialRendererHooks.js
@@ -57,13 +57,15 @@ let currentHookNameInDev: ?string;
function resolveCurrentlyRenderingComponent(): Object {
invariant(
currentlyRenderingComponent !== null,
- 'Hooks can only be called inside the body of a function component.',
+ 'Hooks can only be called inside the body of a function component. ' +
+ '(https://fb.me/react-invalid-hook-call)',
);
if (__DEV__) {
warning(
!isInHookUserCodeInDev,
- 'Hooks can only be called inside the body of a function component. ' +
- 'Do not call Hooks inside other Hooks. For more information, see ' +
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +
+ 'You can only call Hooks at the top level of your React function. ' +
+ 'For more information, see ' +
'https://fb.me/rules-of-hooks',
);
}
diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js
index e05a15d72774..1a0655807f1e 100644
--- a/packages/react-reconciler/src/ReactFiberHooks.js
+++ b/packages/react-reconciler/src/ReactFiberHooks.js
@@ -235,7 +235,8 @@ function warnOnHookMismatchInDev() {
function throwInvalidHookError() {
invariant(
false,
- 'Hooks can only be called inside the body of a function component.',
+ 'Hooks can only be called inside the body of a function component. ' +
+ '(https://fb.me/react-invalid-hook-call)',
);
}
@@ -1188,8 +1189,9 @@ if (__DEV__) {
const warnInvalidHookAccess = () => {
warning(
false,
- 'Hooks can only be called inside the body of a function component. ' +
- 'Do not call Hooks inside other Hooks. For more information, see ' +
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +
+ 'You can only call Hooks at the top level of your React function. ' +
+ 'For more information, see ' +
'https://fb.me/rules-of-hooks',
);
};
diff --git a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
index 43010aac5e62..5b1477a20572 100644
--- a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
@@ -665,7 +665,7 @@ describe('ReactHooks', () => {
return null;
}
expect(() => ReactTestRenderer.create()).toWarnDev(
- 'Hooks can only be called inside the body of a function component',
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks.',
);
});
@@ -835,12 +835,12 @@ describe('ReactHooks', () => {
if (__DEV__) {
expect(console.error).toHaveBeenCalledTimes(3);
expect(console.error.calls.argsFor(0)[0]).toContain(
- 'Hooks can only be called inside the body of a function component',
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks',
);
}
});
- it("throws when calling hooks inside useState's initialize function", () => {
+ it("warns when calling hooks inside useState's initialize function", () => {
const {useState, useRef} = React;
function App() {
useState(() => {
@@ -850,7 +850,7 @@ describe('ReactHooks', () => {
return null;
}
expect(() => ReactTestRenderer.create()).toWarnDev(
- 'Hooks can only be called inside the body of a function component',
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks.',
);
});
@@ -892,9 +892,9 @@ describe('ReactHooks', () => {
}).toWarnDev([
// We see it twice due to replay
'Context can only be read while React is rendering',
- 'Hooks can only be called inside the body of a function component',
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks',
'Context can only be read while React is rendering',
- 'Hooks can only be called inside the body of a function component',
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks',
]);
function Valid() {
@@ -925,9 +925,9 @@ describe('ReactHooks', () => {
}).toWarnDev([
// We see it twice due to replay
'Context can only be read while React is rendering',
- 'Hooks can only be called inside the body of a function component',
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks',
'Context can only be read while React is rendering',
- 'Hooks can only be called inside the body of a function component',
+ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks',
]);
});
diff --git a/packages/react-test-renderer/src/ReactShallowRenderer.js b/packages/react-test-renderer/src/ReactShallowRenderer.js
index 0701854452f2..7472556c6895 100644
--- a/packages/react-test-renderer/src/ReactShallowRenderer.js
+++ b/packages/react-test-renderer/src/ReactShallowRenderer.js
@@ -218,7 +218,8 @@ class ReactShallowRenderer {
_validateCurrentlyRenderingComponent() {
invariant(
this._currentlyRenderingComponent !== null,
- 'Hooks can only be called inside the body of a function component.',
+ 'Hooks can only be called inside the body of a function component. ' +
+ '(https://fb.me/react-invalid-hook-call)',
);
}
diff --git a/packages/react/src/ReactHooks.js b/packages/react/src/ReactHooks.js
index b0debda90e34..271acb4bede9 100644
--- a/packages/react/src/ReactHooks.js
+++ b/packages/react/src/ReactHooks.js
@@ -17,7 +17,8 @@ function resolveDispatcher() {
const dispatcher = ReactCurrentDispatcher.current;
invariant(
dispatcher !== null,
- 'Hooks can only be called inside the body of a function component.',
+ 'Hooks can only be called inside the body of a function component. ' +
+ '(https://fb.me/react-invalid-hook-call)',
);
return dispatcher;
}