Skip to content

Commit 9e3fa49

Browse files
committed
[ESLint] Disallow hooks in async functions
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.
1 parent 53ac219 commit 9e3fa49

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,30 @@ const tests = {
10421042
`,
10431043
errors: [classError('useState')],
10441044
},
1045+
{
1046+
code: normalizeIndent`
1047+
async function AsyncComponent() {
1048+
useState();
1049+
}
1050+
`,
1051+
errors: [asyncComponentHookError('useState')],
1052+
},
1053+
{
1054+
code: normalizeIndent`
1055+
async function AsyncComponent() {
1056+
use();
1057+
}
1058+
`,
1059+
errors: [asyncComponentHookError('use')],
1060+
},
1061+
{
1062+
code: normalizeIndent`
1063+
async function useAsyncHook() {
1064+
use();
1065+
}
1066+
`,
1067+
errors: [asyncComponentHookError('use')],
1068+
},
10451069
],
10461070
};
10471071

@@ -1368,6 +1392,12 @@ function useEffectEventError(fn) {
13681392
};
13691393
}
13701394

1395+
function asyncComponentHookError(fn) {
1396+
return {
1397+
message: `React Hook "${fn}" cannot be called in an async function.`,
1398+
};
1399+
}
1400+
13711401
// For easier local testing
13721402
if (!process.env.CI) {
13731403
let only = [];

packages/eslint-plugin-react-hooks/src/RulesOfHooks.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,16 @@ export default {
485485
// Pick a special message depending on the scope this hook was
486486
// called in.
487487
if (isDirectlyInsideComponentOrHook) {
488+
const isAsyncFunction = codePathNode.async;
489+
if (isAsyncFunction) {
490+
context.report({
491+
node: hook,
492+
message:
493+
`React Hook "${context.getSource(hook)}" cannot be ` +
494+
'called in an async function.',
495+
});
496+
}
497+
488498
// Report an error if a hook does not reach all finalizing code
489499
// path segments.
490500
//

0 commit comments

Comments
 (0)