update error message to include useLayoutEffect or useEffect on bad e… (#22279)

* update error message to include useLayoutEffect or useEffect on bad effect return

* Update packages/react-reconciler/src/ReactFiberCommitWork.new.js

Co-authored-by: Ricky <rickhanlonii@gmail.com>

* use existing import

Co-authored-by: Ricky <rickhanlonii@gmail.com>
This commit is contained in:
salazarm
2021-09-10 12:19:51 -04:00
committed by GitHub
parent cb8a50619b
commit 0fd195f295
3 changed files with 35 additions and 15 deletions
@@ -507,7 +507,7 @@ function commitHookEffectListUnmount(
}
}
function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
function commitHookEffectListMount(tag: HookFlags, finishedWork: Fiber) {
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
@@ -522,6 +522,12 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
if (__DEV__) {
const destroy = effect.destroy;
if (destroy !== undefined && typeof destroy !== 'function') {
let hookName;
if ((effect.tag & HookLayout) !== NoFlags) {
hookName = 'useLayoutEffect';
} else {
hookName = 'useEffect';
}
let addendum;
if (destroy === null) {
addendum =
@@ -529,10 +535,13 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
'up, return undefined (or nothing).';
} else if (typeof destroy.then === 'function') {
addendum =
'\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' +
'\n\nIt looks like you wrote ' +
hookName +
'(async () => ...) or returned a Promise. ' +
'Instead, write the async function inside your effect ' +
'and call it immediately:\n\n' +
'useEffect(() => {\n' +
hookName +
'(() => {\n' +
' async function fetchData() {\n' +
' // You can await here\n' +
' const response = await MyAPI.getData(someId);\n' +
@@ -545,8 +554,9 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
addendum = ' You returned: ' + destroy;
}
console.error(
'An effect function must not return anything besides a function, ' +
'%s must not return anything besides a function, ' +
'which is used for clean-up.%s',
hookName,
addendum,
);
}
@@ -507,7 +507,7 @@ function commitHookEffectListUnmount(
}
}
function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
function commitHookEffectListMount(tag: HookFlags, finishedWork: Fiber) {
const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
if (lastEffect !== null) {
@@ -522,6 +522,12 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
if (__DEV__) {
const destroy = effect.destroy;
if (destroy !== undefined && typeof destroy !== 'function') {
let hookName;
if ((effect.tag & HookLayout) !== NoFlags) {
hookName = 'useLayoutEffect';
} else {
hookName = 'useEffect';
}
let addendum;
if (destroy === null) {
addendum =
@@ -529,10 +535,13 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
'up, return undefined (or nothing).';
} else if (typeof destroy.then === 'function') {
addendum =
'\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' +
'\n\nIt looks like you wrote ' +
hookName +
'(async () => ...) or returned a Promise. ' +
'Instead, write the async function inside your effect ' +
'and call it immediately:\n\n' +
'useEffect(() => {\n' +
hookName +
'(() => {\n' +
' async function fetchData() {\n' +
' // You can await here\n' +
' const response = await MyAPI.getData(someId);\n' +
@@ -545,8 +554,9 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
addendum = ' You returned: ' + destroy;
}
console.error(
'An effect function must not return anything besides a function, ' +
'%s must not return anything besides a function, ' +
'which is used for clean-up.%s',
hookName,
addendum,
);
}
@@ -2647,7 +2647,7 @@ describe('ReactHooksWithNoopRenderer', () => {
root1.render(<App return={17} />);
}),
).toErrorDev([
'Warning: An effect function must not return anything besides a ' +
'Warning: useEffect must not return anything besides a ' +
'function, which is used for clean-up. You returned: 17',
]);
@@ -2657,7 +2657,7 @@ describe('ReactHooksWithNoopRenderer', () => {
root2.render(<App return={null} />);
}),
).toErrorDev([
'Warning: An effect function must not return anything besides a ' +
'Warning: useEffect must not return anything besides a ' +
'function, which is used for clean-up. You returned null. If your ' +
'effect does not require clean up, return undefined (or nothing).',
]);
@@ -2668,7 +2668,7 @@ describe('ReactHooksWithNoopRenderer', () => {
root3.render(<App return={Promise.resolve()} />);
}),
).toErrorDev([
'Warning: An effect function must not return anything besides a ' +
'Warning: useEffect must not return anything besides a ' +
'function, which is used for clean-up.\n\n' +
'It looks like you wrote useEffect(async () => ...) or returned a Promise.',
]);
@@ -2873,7 +2873,7 @@ describe('ReactHooksWithNoopRenderer', () => {
root1.render(<App return={17} />);
}),
).toErrorDev([
'Warning: An effect function must not return anything besides a ' +
'Warning: useLayoutEffect must not return anything besides a ' +
'function, which is used for clean-up. You returned: 17',
]);
@@ -2883,7 +2883,7 @@ describe('ReactHooksWithNoopRenderer', () => {
root2.render(<App return={null} />);
}),
).toErrorDev([
'Warning: An effect function must not return anything besides a ' +
'Warning: useLayoutEffect must not return anything besides a ' +
'function, which is used for clean-up. You returned null. If your ' +
'effect does not require clean up, return undefined (or nothing).',
]);
@@ -2894,9 +2894,9 @@ describe('ReactHooksWithNoopRenderer', () => {
root3.render(<App return={Promise.resolve()} />);
}),
).toErrorDev([
'Warning: An effect function must not return anything besides a ' +
'Warning: useLayoutEffect must not return anything besides a ' +
'function, which is used for clean-up.\n\n' +
'It looks like you wrote useEffect(async () => ...) or returned a Promise.',
'It looks like you wrote useLayoutEffect(async () => ...) or returned a Promise.',
]);
// Error on unmount because React assumes the value is a function