fix(eslint-plugin-query): track custom query hook wrappers in deps#10829
fix(eslint-plugin-query): track custom query hook wrappers in deps#10829raashish1601 wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThe PR extends the ChangesCustom Hook Wrapper Tracking
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts (1)
195-206: 💤 Low valueMissing
useprefix check for function declarations.The
VariableDeclaratorvisitor explicitly checksnode.id.name.startsWith('use')(line 211), but thisFunctionDeclarationvisitor doesn't. This inconsistency could lead to tracking non-hook functions likefunction getQuery() { return useQuery(...) }unnecessarily.♻️ Add prefix check for consistency
FunctionDeclaration(node: TSESTree.FunctionDeclaration) { if (!node.id || node.id.type !== AST_NODE_TYPES.Identifier) { return } + if (!node.id.name.startsWith('use')) { + return + } const returnedHookName = getFunctionReturnedHookName(node)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts` around lines 195 - 206, The FunctionDeclaration visitor currently records any function that returns a hook via getFunctionReturnedHookName into trackedCustomHooks without verifying the function name prefix; add the same name-prefix guard used in the VariableDeclarator visitor by checking node.id.name.startsWith('use') inside the FunctionDeclaration handler and only assign trackedCustomHooks[node.id.name] = returnedHookName when that check passes to avoid tracking non-hook functions (refer to FunctionDeclaration, VariableDeclarator, getFunctionReturnedHookName, and trackedCustomHooks).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts`:
- Around line 252-254: The current check only pushes to
pendingCustomHookAssignments when resolveTrackedHook (resolvedQueryHook) is
truthy, which misses forward-referenced custom hooks; change the logic in the
visitor handling use* calls so that any non-TanStack call (i.e., custom hook
candidates determined by calleeName / isTanStackHook) is always added to
pendingCustomHookAssignments (push { id: node.id, calleeName }) for deferred
resolution, instead of gating the push on resolvedQueryHook; keep
resolveTrackedHook/trackedCustomHooks usage for later resolution but ensure
pendingCustomHookAssignments is populated unconditionally for custom hooks to
handle forward references.
---
Nitpick comments:
In
`@packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts`:
- Around line 195-206: The FunctionDeclaration visitor currently records any
function that returns a hook via getFunctionReturnedHookName into
trackedCustomHooks without verifying the function name prefix; add the same
name-prefix guard used in the VariableDeclarator visitor by checking
node.id.name.startsWith('use') inside the FunctionDeclaration handler and only
assign trackedCustomHooks[node.id.name] = returnedHookName when that check
passes to avoid tracking non-hook functions (refer to FunctionDeclaration,
VariableDeclarator, getFunctionReturnedHookName, and trackedCustomHooks).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 24b9c6b9-8fba-4fb0-b909-689e9897c31d
📒 Files selected for processing (2)
packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.tspackages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts
| if (resolvedQueryHook) { | ||
| pendingCustomHookAssignments.push({ id: node.id, calleeName }) | ||
| } |
There was a problem hiding this comment.
Forward-reference custom hooks won't be tracked.
The condition if (resolvedQueryHook) only pushes to pendingCustomHookAssignments when the hook is already resolvable at visit time. Since ESLint visits nodes in tree order, a custom hook defined after its usage in the file won't be in trackedCustomHooks yet, causing resolveTrackedHook to return undefined and skipping the push. This defeats the purpose of the deferred mechanism.
Example that would be missed:
function Component() {
const query = useMyQuery(); // visited first
useEffect(() => {}, [query]); // false negative
}
function useMyQuery() { return useQuery({...}); } // visited second🐛 Proposed fix: Always defer non-TanStack `use*` calls
- if (resolvedQueryHook) {
- pendingCustomHookAssignments.push({ id: node.id, calleeName })
- }
+ // Always defer - custom hook may be defined later in file
+ pendingCustomHookAssignments.push({ id: node.id, calleeName })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts`
around lines 252 - 254, The current check only pushes to
pendingCustomHookAssignments when resolveTrackedHook (resolvedQueryHook) is
truthy, which misses forward-referenced custom hooks; change the logic in the
visitor handling use* calls so that any non-TanStack call (i.e., custom hook
candidates determined by calleeName / isTanStackHook) is always added to
pendingCustomHookAssignments (push { id: node.id, calleeName }) for deferred
resolution, instead of gating the push on resolvedQueryHook; keep
resolveTrackedHook/trackedCustomHooks usage for later resolution but ensure
pendingCustomHookAssignments is populated unconditionally for custom hooks to
handle forward references.
Description
Handle custom TanStack Query React hook wrappers (including function declarations and nested custom hooks) in the eslint-plugin no-unstable-deps rule.
Changes
Summary by CodeRabbit
Bug Fixes
Tests