From 48f57e340b15f12f95623db6614882290d2826c4 Mon Sep 17 00:00:00 2001 From: leeguooooo Date: Fri, 26 Dec 2025 15:11:06 +0900 Subject: [PATCH] eslint-plugin-react-hooks: disallow hook arguments --- .../__tests__/ESLintRulesOfHooks-test.js | 25 +++++++++++++++++++ .../src/rules/RulesOfHooks.ts | 19 ++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js index 3d60a36824d..f25f10707a4 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js @@ -949,6 +949,23 @@ const allTests = { `, errors: [conditionalError('useConditionalHook')], }, + { + code: normalizeIndent` + function Component() { + const items = [1, 2]; + items.map(useCustomHook); + } + `, + errors: [hookArgumentError('useCustomHook')], + }, + { + code: normalizeIndent` + function Component() { + doSomething(React.useState); + } + `, + errors: [hookArgumentError('React.useState')], + }, { code: normalizeIndent` Hook.useState(); @@ -2062,6 +2079,14 @@ function genericError(hook) { }; } +function hookArgumentError(hook) { + return { + message: + `React Hook "${hook}" cannot be passed as an argument. React Hooks ` + + 'must be called in a React function component or a custom React Hook function.', + }; +} + function topLevelError(hook) { return { message: diff --git a/packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts b/packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts index ca82c99e2f5..e46c3aac774 100644 --- a/packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts +++ b/packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts @@ -767,6 +767,25 @@ const rule = { reactHooks.push(node.callee); } + if (isInsideComponentOrHook(node)) { + for (const argument of node.arguments) { + if ( + argument && + argument.type !== 'SpreadElement' && + isHook(argument) + ) { + context.report({ + node: argument, + message: + `React Hook "${getSourceCode().getText( + argument, + )}" cannot be passed as an argument. React Hooks ` + + 'must be called in a React function component or a custom React Hook function.', + }); + } + } + } + // useEffectEvent: useEffectEvent functions can be passed by reference within useEffect as well as in // another useEffectEvent // Check all `useEffect` and `React.useEffect`, `useEffectEvent`, and `React.useEffectEvent`