@samitouri / QOS-React-2 / commits / 0fd195f295

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>

salazarm committed Sep 10, 2021 at 12:19 UTC 0fd195f2955478636ccab840676c19bb29874b96
3 files changed +35 -15
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+14 -4
@@ -507,7 +507,7 @@ function commitHookEffectListUnmount(
507 }
508 }
509
510 -function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
510 +function commitHookEffectListMount(tag: HookFlags, finishedWork: Fiber) {
511 const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
512 const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
513 if (lastEffect !== null) {
@@ -522,6 +522,12 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
522 if (__DEV__) {
523 const destroy = effect.destroy;
524 if (destroy !== undefined && typeof destroy !== 'function') {
525 + let hookName;
526 + if ((effect.tag & HookLayout) !== NoFlags) {
527 + hookName = 'useLayoutEffect';
528 + } else {
529 + hookName = 'useEffect';
530 + }
531 let addendum;
532 if (destroy === null) {
533 addendum =
@@ -529,10 +535,13 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
535 'up, return undefined (or nothing).';
536 } else if (typeof destroy.then === 'function') {
537 addendum =
532 - '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' +
538 + '\n\nIt looks like you wrote ' +
539 + hookName +
540 + '(async () => ...) or returned a Promise. ' +
541 'Instead, write the async function inside your effect ' +
542 'and call it immediately:\n\n' +
535 - 'useEffect(() => {\n' +
543 + hookName +
544 + '(() => {\n' +
545 ' async function fetchData() {\n' +
546 ' // You can await here\n' +
547 ' const response = await MyAPI.getData(someId);\n' +
@@ -545,8 +554,9 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
554 addendum = ' You returned: ' + destroy;
555 }
556 console.error(
548 - 'An effect function must not return anything besides a function, ' +
557 + '%s must not return anything besides a function, ' +
558 'which is used for clean-up.%s',
559 + hookName,
560 addendum,
561 );
562 }
packages/react-reconciler/src/ReactFiberCommitWork.old.js
+14 -4
@@ -507,7 +507,7 @@ function commitHookEffectListUnmount(
507 }
508 }
509
510 -function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
510 +function commitHookEffectListMount(tag: HookFlags, finishedWork: Fiber) {
511 const updateQueue: FunctionComponentUpdateQueue | null = (finishedWork.updateQueue: any);
512 const lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
513 if (lastEffect !== null) {
@@ -522,6 +522,12 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
522 if (__DEV__) {
523 const destroy = effect.destroy;
524 if (destroy !== undefined && typeof destroy !== 'function') {
525 + let hookName;
526 + if ((effect.tag & HookLayout) !== NoFlags) {
527 + hookName = 'useLayoutEffect';
528 + } else {
529 + hookName = 'useEffect';
530 + }
531 let addendum;
532 if (destroy === null) {
533 addendum =
@@ -529,10 +535,13 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
535 'up, return undefined (or nothing).';
536 } else if (typeof destroy.then === 'function') {
537 addendum =
532 - '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' +
538 + '\n\nIt looks like you wrote ' +
539 + hookName +
540 + '(async () => ...) or returned a Promise. ' +
541 'Instead, write the async function inside your effect ' +
542 'and call it immediately:\n\n' +
535 - 'useEffect(() => {\n' +
543 + hookName +
544 + '(() => {\n' +
545 ' async function fetchData() {\n' +
546 ' // You can await here\n' +
547 ' const response = await MyAPI.getData(someId);\n' +
@@ -545,8 +554,9 @@ function commitHookEffectListMount(tag: number, finishedWork: Fiber) {
554 addendum = ' You returned: ' + destroy;
555 }
556 console.error(
548 - 'An effect function must not return anything besides a function, ' +
557 + '%s must not return anything besides a function, ' +
558 'which is used for clean-up.%s',
559 + hookName,
560 addendum,
561 );
562 }
packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+7 -7
@@ -2647,7 +2647,7 @@ describe('ReactHooksWithNoopRenderer', () => {
2647 root1.render(<App return={17} />);
2648 }),
2649 ).toErrorDev([
2650 - 'Warning: An effect function must not return anything besides a ' +
2650 + 'Warning: useEffect must not return anything besides a ' +
2651 'function, which is used for clean-up. You returned: 17',
2652 ]);
2653
@@ -2657,7 +2657,7 @@ describe('ReactHooksWithNoopRenderer', () => {
2657 root2.render(<App return={null} />);
2658 }),
2659 ).toErrorDev([
2660 - 'Warning: An effect function must not return anything besides a ' +
2660 + 'Warning: useEffect must not return anything besides a ' +
2661 'function, which is used for clean-up. You returned null. If your ' +
2662 'effect does not require clean up, return undefined (or nothing).',
2663 ]);
@@ -2668,7 +2668,7 @@ describe('ReactHooksWithNoopRenderer', () => {
2668 root3.render(<App return={Promise.resolve()} />);
2669 }),
2670 ).toErrorDev([
2671 - 'Warning: An effect function must not return anything besides a ' +
2671 + 'Warning: useEffect must not return anything besides a ' +
2672 'function, which is used for clean-up.\n\n' +
2673 'It looks like you wrote useEffect(async () => ...) or returned a Promise.',
2674 ]);
@@ -2873,7 +2873,7 @@ describe('ReactHooksWithNoopRenderer', () => {
2873 root1.render(<App return={17} />);
2874 }),
2875 ).toErrorDev([
2876 - 'Warning: An effect function must not return anything besides a ' +
2876 + 'Warning: useLayoutEffect must not return anything besides a ' +
2877 'function, which is used for clean-up. You returned: 17',
2878 ]);
2879
@@ -2883,7 +2883,7 @@ describe('ReactHooksWithNoopRenderer', () => {
2883 root2.render(<App return={null} />);
2884 }),
2885 ).toErrorDev([
2886 - 'Warning: An effect function must not return anything besides a ' +
2886 + 'Warning: useLayoutEffect must not return anything besides a ' +
2887 'function, which is used for clean-up. You returned null. If your ' +
2888 'effect does not require clean up, return undefined (or nothing).',
2889 ]);
@@ -2894,9 +2894,9 @@ describe('ReactHooksWithNoopRenderer', () => {
2894 root3.render(<App return={Promise.resolve()} />);
2895 }),
2896 ).toErrorDev([
2897 - 'Warning: An effect function must not return anything besides a ' +
2897 + 'Warning: useLayoutEffect must not return anything besides a ' +
2898 'function, which is used for clean-up.\n\n' +
2899 - 'It looks like you wrote useEffect(async () => ...) or returned a Promise.',
2899 + 'It looks like you wrote useLayoutEffect(async () => ...) or returned a Promise.',
2900 ]);
2901
2902 // Error on unmount because React assumes the value is a function