Skip to content

Conversation

alimttth
Copy link

@alimttth alimttth commented Oct 1, 2025

Changes

Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm test:pr.

Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Bug Fixes

    • Linting now treats useQueries calls that include a combine option as stable, avoiding false-positive no-unstable-deps warnings in React hooks.
  • Tests

    • Added tests covering useQueries with and without combine, validating correct diagnostics for stable and unstable dependency patterns (including cases passing the queries object as a hook dependency).

- Add hasCombineProperty function to detect combine property in useQueries calls
- Skip tracking useQueries with combine as unstable since combine makes result stable
- Add tests for useQueries with and without combine property
- Fixes TanStack#9718
Copy link

changeset-bot bot commented Oct 1, 2025

⚠️ No Changeset found

Latest commit: 28e98fa

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Oct 1, 2025

Walkthrough

Adds handling so useQueries calls with a combine property are treated as stable (skipped) by the no-unstable-deps rule, and extends tests with valid and invalid cases for useQueries with and without combine.

Changes

Cohort / File(s) Summary
Rule logic: handle combine in useQueries
packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts
Adds hasCombineProperty(callExpression) and an early-return in VariableDeclarator handling when useQueries is called with a combine property, so the resulting variable is not tracked as unstable.
Tests: extend valid/invalid cases
packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts
Appends new valid and invalid test cases covering useQueries with a combine function (treated as stable) and useQueries without combine (still reported), including dependency-array and property-access scenarios.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer Code
  participant ESLint as no-unstable-deps Rule
  participant AST as AST Walker

  Dev->>ESLint: Run lint on file
  ESLint->>AST: Visit VariableDeclarator (init is CallExpression)
  alt callee is useQueries with combine
    note right of ESLint #a9d18e: Detect combine on first argument (treated stable)
    ESLint-->>AST: Skip tracking variable
  else callee is useQueries without combine
    note right of ESLint #f4c7c3: No combine (treated unstable)
    ESLint->>AST: Track variable as unstable
  end

  AST->>ESLint: Visit React Hook call with deps
  alt deps reference tracked (unstable) variable
    ESLint-->>Dev: Report noUnstableDeps diagnostic
  else deps reference skipped/stable variable
    ESLint-->>Dev: No diagnostic
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • Newbie012
  • TkDodo

Poem

A whisker twitch, a combine switch, hooray!
I skip the chase where stable things lay.
No noisy lint, just calm delight—
I hop and nibble through the night.
Carrots for code that’s doing right. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description does not follow the repository’s template because the “## 🎯 Changes” section is missing or empty, the placeholder under "## Changes" remains unfilled, and section headings do not match the required template structure. Please restructure the description to use the “## 🎯 Changes” header with a filled summary of changes, remove or replace template placeholders under “## Changes,” and ensure all required sections and headings match the repository’s description template.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely summarizes the main change by stating that the no-unstable-deps rule is fixed to allow useQueries with the combine property, matching the PR’s purpose and following conventional commit style.
Linked Issues Check ✅ Passed The changes implement a helper to detect the combine property and skip tracking for useQueries with combine, update the ESLint rule accordingly, and include tests for both combine and non-combine scenarios, fully addressing the objectives from issue #9718.
Out of Scope Changes Check ✅ Passed All modifications are confined to the no-unstable-deps ESLint rule and its test file to support useQueries with combine, and there are no unrelated or extraneous changes outside the linked issue’s scope.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6cfbf0 and 28e98fa.

📒 Files selected for processing (2)
  • packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts (4 hunks)
  • packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts
  • packages/eslint-plugin-query/src/tests/no-unstable-deps.test.ts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts (1)

70-81: Consider edge cases in combine property detection.

The function correctly identifies standard combine properties, but may not handle all edge cases:

  1. Spread properties: { ...config, queries: [...] } won't be detected if combine is in the spread
  2. Computed property names: { ['combine']: fn } won't match since you check prop.key.type === AST_NODE_TYPES.Identifier
  3. Property shorthand: While { combine } should work, the function assumes the property key name is what matters

For robustness, consider adding a check for computed properties:

 function hasCombineProperty(callExpression: TSESTree.CallExpression): boolean {
   if (callExpression.arguments.length === 0) return false
 
   const firstArg = callExpression.arguments[0]
   if (!firstArg || firstArg.type !== AST_NODE_TYPES.ObjectExpression) return false
 
   return firstArg.properties.some(prop =>
     prop.type === AST_NODE_TYPES.Property &&
+    !prop.computed &&
     prop.key.type === AST_NODE_TYPES.Identifier &&
     prop.key.name === 'combine'
   )
 }

This ensures computed properties like { ['combine']: fn } are excluded (though they're unlikely in practice).

packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts (1)

110-134: Consider adding invalid test case for useSuspenseQueries without combine.

The invalid test case correctly verifies that useQueries without combine triggers the rule. For completeness and symmetry with the valid test cases, consider adding a corresponding invalid test for useSuspenseQueries without combine.

Add this test case to the invalid array:

{
  name: `result of useSuspenseQueries without combine is passed to ${reactHookInvocation} as dependency`,
  code: `
      ${reactHookImport}
      import { useSuspenseQueries } from "@tanstack/react-query";

      function Component() {
        const queries = useSuspenseQueries({
          queries: [
            { queryKey: ['test'], queryFn: () => 'test' }
          ]
        });
        const callback = ${reactHookInvocation}(() => { queries[0]?.data }, [queries]);
        return;
      }
    `,
  errors: [
    {
      messageId: 'noUnstableDeps',
      data: { reactHook: reactHookAlias, queryHook: 'useSuspenseQueries' },
    },
  ],
},
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f82d8e and c6cfbf0.

📒 Files selected for processing (2)
  • packages/eslint-plugin-query/src/__tests__/no-unstable-deps.test.ts (2 hunks)
  • packages/eslint-plugin-query/src/rules/no-unstable-deps/no-unstable-deps.rule.ts (2 hunks)

Copy link

nx-cloud bot commented Oct 4, 2025

View your CI Pipeline Execution ↗ for commit 28e98fa

Command Status Duration Result
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 5s View ↗

☁️ Nx Cloud last updated this comment at 2025-10-04 19:56:57 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

False positive in @tanstack/query/no-unstable-deps ESLint rule with combine property
1 participant