fix(eslint-plugin-query): handle array-destructured useQueries results in no-unstable-deps (fix #10746)#10747
fix(eslint-plugin-query): handle array-destructured useQueries results in no-unstable-deps (fix #10746)#10747vinamra1102 wants to merge 4 commits into
Conversation
…s in no-unstable-deps The `collectVariableNames` function in the `no-unstable-deps` rule only handled `Identifier` patterns. When users array-destructure `useQueries` or `useSuspenseQueries` results (e.g. `const [q1, q2] = useQueries(...)`), the individual variables were not tracked as unstable. This meant passing them directly to React hook dependency arrays was never flagged. Extend `collectVariableNames` to also handle `ArrayPattern` — including plain identifier elements and rest elements. Fixes TanStack#10746
…tern fix(eslint-plugin-query): handle array-destructured useQueries result…
📝 WalkthroughWalkthroughFixes a false negative in the ChangesArray Destructuring Support for no-unstable-deps
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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
🤖 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 67-80: In collectVariableNames, ArrayPattern handling currently
only records Identifier and RestElement identifiers and misses AssignmentPattern
elements (e.g., const [q = fallback] = useQueries(...)); add a branch to treat
element.type === AST_NODE_TYPES.AssignmentPattern and, when element.left.type
=== AST_NODE_TYPES.Identifier, register trackedVariables[element.left.name] =
queryHook (similarly handle RestElement whose argument might be an
AssignmentPattern if applicable) so default-value array destructuring is
tracked.
🪄 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: a3f0b505-6822-4e93-aa85-85c7e1e82dfc
📒 Files selected for processing (3)
.changeset/fix-no-unstable-deps-array-pattern.mdpackages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.tspackages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts
|
Updated the PR to also handle Workflows are awaiting approval could a maintainer please approve |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts (1)
205-276: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winAdd one regression test for default-value array destructuring (
AssignmentPattern).Please add an invalid case like
const [query = fallback] = useQueries(...)(and/oruseSuspenseQueries) used in deps, so this path is locked by tests alongside element/rest coverage.🤖 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/__tests__/no-unstable-deps.test.ts` around lines 205 - 276, Add a failing test that covers array-destructuring with a default value (AssignmentPattern) being used in hook deps: add cases similar to the existing ones that declare "const [query = fallback] = useQueries(...)" and "const [query = fallback] = useSuspenseQueries(...)" and then pass `query` in the dependency array for the dynamic react hook invocation (use the existing test variables reactHookImport, reactHookInvocation/reactHookAlias and queryHook names). Ensure each test includes an errors entry with messageId 'noUnstableDeps' and data { reactHook: reactHookAlias, queryHook: 'useQueries' } or 'useSuspenseQueries' as appropriate so the AssignmentPattern path is exercised.
♻️ Duplicate comments (1)
packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts (1)
67-80:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMissing
AssignmentPatternsupport in array destructuring still leaves a false-negative path.
collectVariableNamesstill skips cases likeconst [query = fallback] = useQueries(...), so those bindings won’t be tracked and won’t be reported in dependency arrays. Please recurse onAssignmentPattern.leftin theArrayPatternloop.#!/bin/bash # Verify whether AssignmentPattern is handled in collectVariableNames and whether related tests exist. rg -n "function collectVariableNames|ArrayPattern|AssignmentPattern|RestElement" \ packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts -C4 rg -n "useQueries|useSuspenseQueries|\\[.*=.*\\]|AssignmentPattern" \ packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts -C3🤖 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 67 - 80, collectVariableNames currently ignores AssignmentPattern nodes inside an ArrayPattern (e.g., const [query = fallback] = useQueries(...)), causing false-negatives; update the ArrayPattern handling in collectVariableNames to detect when an element.type === AST_NODE_TYPES.AssignmentPattern and then recurse or process its left child (element.left) the same way you handle an Identifier (and RestElement.argument), adding trackedVariables[element.left.name] = queryHook (or delegating to collectVariableNames on element.left) so defaulted bindings are tracked.
🤖 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.
Outside diff comments:
In `@packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts`:
- Around line 205-276: Add a failing test that covers array-destructuring with a
default value (AssignmentPattern) being used in hook deps: add cases similar to
the existing ones that declare "const [query = fallback] = useQueries(...)" and
"const [query = fallback] = useSuspenseQueries(...)" and then pass `query` in
the dependency array for the dynamic react hook invocation (use the existing
test variables reactHookImport, reactHookInvocation/reactHookAlias and queryHook
names). Ensure each test includes an errors entry with messageId
'noUnstableDeps' and data { reactHook: reactHookAlias, queryHook: 'useQueries' }
or 'useSuspenseQueries' as appropriate so the AssignmentPattern path is
exercised.
---
Duplicate comments:
In
`@packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts`:
- Around line 67-80: collectVariableNames currently ignores AssignmentPattern
nodes inside an ArrayPattern (e.g., const [query = fallback] = useQueries(...)),
causing false-negatives; update the ArrayPattern handling in
collectVariableNames to detect when an element.type ===
AST_NODE_TYPES.AssignmentPattern and then recurse or process its left child
(element.left) the same way you handle an Identifier (and RestElement.argument),
adding trackedVariables[element.left.name] = queryHook (or delegating to
collectVariableNames on element.left) so defaulted bindings are tracked.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: dd8c54c6-1809-4bba-b223-cd2ba9b71c45
📒 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
What does this PR fix?
The
no-unstable-depsrule silently ignores array-destructured resultsfrom
useQueriesanduseSuspenseQueries. Writing:const [userQuery, postsQuery] = useQueries({ queries: [...] })
causes neither variable to be tracked as unstable, so using them in
useEffectdependency arrays is never flagged — even though it should be.Root cause
collectVariableNamesinno-unstable-deps.rule.tsonly handledIdentifierpatterns. When the result is array-destructured, theidnode is an
ArrayPatternwhich was silently ignored.Evidence this is unintentional
The sibling rule
no-rest-destructuringalready handlesArrayPatterncorrectly for
useQueriesanduseSuspenseQueries(lines 69–86 ofno-rest-destructuring.rule.ts), confirming this pattern is expectedand
no-unstable-depshad a gap.Fix
Added
ArrayPatternhandling tocollectVariableNamesto iterate overelements and track each destructured variable individually, including
rest elements.
Tests added
useQueriesarray element used as dep → flaggeduseSuspenseQueriesarray element used as dep → flagged...restQueries) used as dep → flaggedRelated issue
Fixes #10746
Summary by CodeRabbit
Bug Fixes
Tests
Chores