From 024bfa0cb0f92eff9e984247919515a10224cc86 Mon Sep 17 00:00:00 2001 From: Rel1cx Date: Wed, 5 Mar 2025 12:30:42 +0800 Subject: [PATCH] fix(plugins/hooks-extra): misidentification of 'set' function in IIFE inside of hooks as its inside of 'useEffect', 'useLayoutEffect', closes #967 --- .../use-no-direct-set-state-in-use-effect.ts | 5 +++-- .../no-direct-set-state-in-use-effect.spec.ts | 16 ++++++++++++++++ .../src/rules/no-children-prop.md | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/plugins/eslint-plugin-react-hooks-extra/src/hooks/use-no-direct-set-state-in-use-effect.ts b/packages/plugins/eslint-plugin-react-hooks-extra/src/hooks/use-no-direct-set-state-in-use-effect.ts index c76b6c08f..5f0bd2f52 100644 --- a/packages/plugins/eslint-plugin-react-hooks-extra/src/hooks/use-no-direct-set-state-in-use-effect.ts +++ b/packages/plugins/eslint-plugin-react-hooks-extra/src/hooks/use-no-direct-set-state-in-use-effect.ts @@ -107,8 +107,9 @@ export function useNoDirectSetStateInUseEffect( match(getCallKind(node)) .with("setState", () => { switch (true) { - case pEntry.node === setupFunction - || pEntry.kind === "immediate": { + case pEntry.node === setupFunction: + case pEntry.kind === "immediate" + && AST.findParentNode(pEntry.node, AST.isFunction) === setupFunction: { onViolation(context, node, { name: context.sourceCode.getText(node.callee), }); diff --git a/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.spec.ts b/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.spec.ts index 970b2dd4c..ffa888d89 100644 --- a/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.spec.ts +++ b/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.spec.ts @@ -785,5 +785,21 @@ ruleTester.run(RULE_NAME, rule, { // ...use tooltipHeight in the rendering logic below... } `, + // https://github.com/Rel1cx/eslint-react/issues/967 + /* tsx */ ` + import { useEffect, useState, useCallback } from "react"; + + function useCustomHook() { + const [something, setSomething] = useState(''); + + const test = useCallback(() => { + setSomething('') // doesn't trigger the rules + + ;(() => { + setSomething('') // trigger the rules + })() + }, []) + } + `, ], }); diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.md b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.md index 764942853..4fa3c5d87 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.md +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.md @@ -20,7 +20,7 @@ react-x/no-children-prop ## What it does -Disallows passing 'children' as a prop. +Disallows passing `children` as a prop. Most of the time, `children` should be actual `children`, not passed in as a `prop`.