From f35b3c79b8db8aaa705692dff1e65fd34b551898 Mon Sep 17 00:00:00 2001 From: acdlite Date: Wed, 5 Jul 2023 15:49:31 +0000 Subject: [PATCH] [ESLint] Disallow hooks in async functions (#27045) Hooks cannot be called in async functions, on either the client or the server. This mistake sometimes happens when using Server Components, especially when refactoring a Server Component to a Client Component. React logs a warning at runtime, but it's even better to catch this with a lint rule since it will show immediate inline feedback in the editor. I added this to the existing "Rules of Hooks" ESLint rule. DiffTrain build for [7118f5dd7bf5f1c44d0d2944ef8ad58e423909ad](https://github.com/facebook/react/commit/7118f5dd7bf5f1c44d0d2944ef8ad58e423909ad) --- compiled/facebook-www/REVISION | 2 +- compiled/facebook-www/eslint-plugin-react-hooks.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index 510440e79e071..1a2009d3cf6ed 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -5c8dabf8864e1d826c831d6096b2dfa66309961a +7118f5dd7bf5f1c44d0d2944ef8ad58e423909ad diff --git a/compiled/facebook-www/eslint-plugin-react-hooks.js b/compiled/facebook-www/eslint-plugin-react-hooks.js index 2b2b7b3aa4fc0..cd72678619b97 100644 --- a/compiled/facebook-www/eslint-plugin-react-hooks.js +++ b/compiled/facebook-www/eslint-plugin-react-hooks.js @@ -623,10 +623,20 @@ var RulesOfHooks = { if (isDirectlyInsideComponentOrHook) { - // Report an error if a hook does not reach all finalizing code + // Report an error if the hook is called inside an async function. + var isAsyncFunction = codePathNode.async; + + if (isAsyncFunction) { + context.report({ + node: hook, + message: "React Hook \"" + context.getSource(hook) + "\" cannot be " + 'called in an async function.' + }); + } // Report an error if a hook does not reach all finalizing code // path segments. // // Special case when we think there might be an early return. + + if (!cycled && pathsFromStartToEnd !== allPathsFromStartToEnd && !isUseIdentifier(hook) // `use(...)` can be called conditionally. ) { var message = "React Hook \"" + context.getSource(hook) + "\" is called " + 'conditionally. React Hooks must be called in the exact ' + 'same order in every component render.' + (possiblyHasEarlyReturn ? ' Did you accidentally call a React Hook after an' + ' early return?' : '');