-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
feat(eslint-plugin-query): add new rule for SSR QueryClient setup #10061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: ae6d75e The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📝 WalkthroughWalkthroughThis PR adds a new ESLint rule Changes
Sequence Diagram(s)(omitted — changes are an ESLint rule and tests; no multi-component runtime flow to visualize) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@docs/eslint/no-module-query-client.md`:
- Around line 35-51: The "incorrect" example in docs shows new QueryClient()
created inside the MyApp component (queryClient), but the rule
`@tanstack/query/no-module-query-client` only detects module-level creations, so
update the documentation to reflect the rule's actual behavior: either remove or
move the per-render example so it shows QueryClient created at module scope
(e.g., const queryClient = new QueryClient() at top-level) or explicitly state
that the rule only flags module-level (no function ancestor) new QueryClient()
usages; update the text around MyApp/QueryClient/queryClient accordingly to
avoid claiming the shown per-render case is flagged.
🧹 Nitpick comments (3)
docs/eslint/no-module-query-client.md (1)
98-114: TheuseRefexample still creates a newQueryClienton every render.While the ref preserves the first instance, the expression
new QueryClient()is evaluated on every render—the result is just discarded. This wastes resources and could cause issues ifQueryClientconstructor has side effects.Consider updating this example to use lazy initialization:
Suggested lazy initialization pattern
// app/providers.tsx 'use client' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { useRef } from 'react' function getQueryClient() { return new QueryClient() } export function Providers({ children }: { children: React.ReactNode }) { const queryClientRef = useRef<QueryClient | null>(null) if (queryClientRef.current === null) { queryClientRef.current = getQueryClient() } return ( <QueryClientProvider client={queryClientRef.current}> {children} </QueryClientProvider> ) }packages/eslint-plugin-query/src/rules/no-module-query-client/no-module-query-client.rule.ts (1)
56-63: Consider renamingcomponenttofunctionAncestorfor clarity.The variable name
componentsuggests it's specifically a React component, butASTUtils.getFunctionAncestorreturns any enclosing function. This could be a regular function, arrow function, or custom hook—not necessarily a React component.Suggested rename
- const component = ASTUtils.getFunctionAncestor(context.sourceCode, node) + const functionAncestor = ASTUtils.getFunctionAncestor(context.sourceCode, node) - if (component === undefined) { + if (functionAncestor === undefined) { context.report({ node, messageId: 'noModuleQueryClient', }) }packages/eslint-plugin-query/src/__tests__/no-module-query-client.test.ts (1)
75-85: Good coverage for non-Next.js paths.The test correctly verifies that
src/utils/query.tsis not flagged as a Next.js file.Consider adding a test case for potential false positives like
myapp/components/Provider.tsxto ensure the regex doesn't incorrectly match paths whereappis part of a larger directory name.Suggested additional test case
{ name: 'QueryClient at module level in directory containing "app" as substring', filename: 'myapp/components/Provider.tsx', code: normalizeIndent` import { QueryClient } from "@tanstack/react-query"; const queryClient = new QueryClient(); export { queryClient }; `, },
🎯 Changes
Resolves: #10060
New rule for ensuring that
QueryClientisn't created in the root module scope (for Next.js applications)✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
New Features
Documentation
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.