mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user