snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
126
docs/eslint/eslint-plugin-query.md
Normal file
126
docs/eslint/eslint-plugin-query.md
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
id: eslint-plugin-query
|
||||
title: ESLint Plugin Query
|
||||
---
|
||||
|
||||
TanStack Query comes with its own ESLint plugin. This plugin is used to enforce best practices and to help you avoid common mistakes.
|
||||
|
||||
## Installation
|
||||
|
||||
The plugin is a separate package that you need to install:
|
||||
|
||||
```bash
|
||||
npm i -D @tanstack/eslint-plugin-query
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
pnpm add -D @tanstack/eslint-plugin-query
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
yarn add -D @tanstack/eslint-plugin-query
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
bun add -D @tanstack/eslint-plugin-query
|
||||
```
|
||||
|
||||
## Flat Config (`eslint.config.js`)
|
||||
|
||||
### Recommended setup
|
||||
|
||||
To enable all of the recommended rules for our plugin, add the following config:
|
||||
|
||||
```js
|
||||
import pluginQuery from '@tanstack/eslint-plugin-query'
|
||||
|
||||
export default [
|
||||
...pluginQuery.configs['flat/recommended'],
|
||||
// Any other config...
|
||||
]
|
||||
```
|
||||
|
||||
### Recommended strict setup
|
||||
|
||||
The `flat/recommended-strict` config extends `flat/recommended` with additional opinionated rules that enforce best practices more aggressively.
|
||||
|
||||
```js
|
||||
import pluginQuery from '@tanstack/eslint-plugin-query'
|
||||
|
||||
export default [
|
||||
...pluginQuery.configs['flat/recommended-strict'],
|
||||
// Any other config...
|
||||
]
|
||||
```
|
||||
|
||||
### Custom setup
|
||||
|
||||
Alternatively, you can load the plugin and configure only the rules you want to use:
|
||||
|
||||
```js
|
||||
import pluginQuery from '@tanstack/eslint-plugin-query'
|
||||
|
||||
export default [
|
||||
{
|
||||
plugins: {
|
||||
'@tanstack/query': pluginQuery,
|
||||
},
|
||||
rules: {
|
||||
'@tanstack/query/exhaustive-deps': 'error',
|
||||
},
|
||||
},
|
||||
// Any other config...
|
||||
]
|
||||
```
|
||||
|
||||
## Legacy Config (`.eslintrc`)
|
||||
|
||||
### Recommended setup
|
||||
|
||||
To enable all of the recommended rules for our plugin, add `plugin:@tanstack/query/recommended` in extends:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": ["plugin:@tanstack/query/recommended"]
|
||||
}
|
||||
```
|
||||
|
||||
### Recommended strict setup
|
||||
|
||||
The `recommendedStrict` config extends `recommended` with additional opinionated rules:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": ["plugin:@tanstack/query/recommendedStrict"]
|
||||
}
|
||||
```
|
||||
|
||||
### Custom setup
|
||||
|
||||
Alternatively, add `@tanstack/query` to the plugins section, and configure the rules you want to use:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": ["@tanstack/query"],
|
||||
"rules": {
|
||||
"@tanstack/query/exhaustive-deps": "error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- [@tanstack/query/exhaustive-deps](./exhaustive-deps.md)
|
||||
- [@tanstack/query/no-rest-destructuring](./no-rest-destructuring.md)
|
||||
- [@tanstack/query/stable-query-client](./stable-query-client.md)
|
||||
- [@tanstack/query/no-unstable-deps](./no-unstable-deps.md)
|
||||
- [@tanstack/query/infinite-query-property-order](./infinite-query-property-order.md)
|
||||
- [@tanstack/query/no-void-query-fn](./no-void-query-fn.md)
|
||||
- [@tanstack/query/mutation-property-order](./mutation-property-order.md)
|
||||
- [@tanstack/query/prefer-query-options](./prefer-query-options.md)
|
||||
87
docs/eslint/exhaustive-deps.md
Normal file
87
docs/eslint/exhaustive-deps.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
id: exhaustive-deps
|
||||
title: Exhaustive dependencies for query keys
|
||||
---
|
||||
|
||||
Query keys should contain the serializable values that identify the data returned by your queryFn.
|
||||
This makes sure that queries are cached independently and that queries are refetched automatically when those values change.
|
||||
|
||||
Function call targets are not query key dependencies. For example, `fetchTodoById(todoId)` needs `todoId` in the query key, but not `fetchTodoById`. Values referenced inside nested callbacks are still dependencies, so `promise.then(() => todoId)` also needs `todoId` in the query key.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/exhaustive-deps": "error" */
|
||||
|
||||
useQuery({
|
||||
queryKey: ['todo'],
|
||||
queryFn: () => api.getTodo(todoId),
|
||||
})
|
||||
|
||||
const todoQueries = {
|
||||
detail: (id) => ({ queryKey: ['todo'], queryFn: () => api.getTodo(id) }),
|
||||
}
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
const Component = ({ todoId }) => {
|
||||
const todos = useTodos()
|
||||
useQuery({
|
||||
queryKey: ['todo', todoId],
|
||||
queryFn: () => todos.getTodo(todoId),
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
const todos = createTodos()
|
||||
const todoQueries = {
|
||||
detail: (id) => ({
|
||||
queryKey: ['todo', id],
|
||||
queryFn: () => todos.getTodo(id),
|
||||
}),
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// with { allowlist: { types: ["Config"] }}
|
||||
class Config { ... }
|
||||
const Component = ({ todoId, config }: { todoId: string, config: Config }) => {
|
||||
useQuery({
|
||||
queryKey: ['todo', todoId],
|
||||
queryFn: () => fetchTodo(todoId, config.baseUrl),
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
- `allowlist.variables`: An array of variable names that should be ignored when checking dependencies
|
||||
- `allowlist.types`: An array of TypeScript type names that should be ignored when checking dependencies
|
||||
|
||||
```json
|
||||
{
|
||||
"@tanstack/query/exhaustive-deps": [
|
||||
"error",
|
||||
{
|
||||
"allowlist": {
|
||||
"variables": ["api", "config"],
|
||||
"types": ["ApiClient", "Config"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If you don't care about the rules of the query keys, then you will not need this rule.
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended
|
||||
- [x] 🔧 Fixable
|
||||
63
docs/eslint/infinite-query-property-order.md
Normal file
63
docs/eslint/infinite-query-property-order.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
id: infinite-query-property-order
|
||||
title: Ensure correct order of inference sensitive properties for infinite queries
|
||||
---
|
||||
|
||||
For the following functions, the property order of the passed in object matters due to type inference:
|
||||
|
||||
- `useInfiniteQuery`
|
||||
- `useSuspenseInfiniteQuery`
|
||||
- `infiniteQueryOptions`
|
||||
|
||||
The correct property order is as follows:
|
||||
|
||||
- `queryFn`
|
||||
- `getPreviousPageParam`
|
||||
- `getNextPageParam`
|
||||
|
||||
All other properties are insensitive to the order as they do not depend on type inference.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/infinite-query-property-order": "warn" */
|
||||
import { useInfiniteQuery } from '@tanstack/react-query'
|
||||
|
||||
const query = useInfiniteQuery({
|
||||
queryKey: ['projects'],
|
||||
getNextPageParam: (lastPage) => lastPage.nextId ?? undefined,
|
||||
queryFn: async ({ pageParam }) => {
|
||||
const response = await fetch(`/api/projects?cursor=${pageParam}`)
|
||||
return await response.json()
|
||||
},
|
||||
initialPageParam: 0,
|
||||
getPreviousPageParam: (firstPage) => firstPage.previousId ?? undefined,
|
||||
maxPages: 3,
|
||||
})
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/infinite-query-property-order": "warn" */
|
||||
import { useInfiniteQuery } from '@tanstack/react-query'
|
||||
|
||||
const query = useInfiniteQuery({
|
||||
queryKey: ['projects'],
|
||||
queryFn: async ({ pageParam }) => {
|
||||
const response = await fetch(`/api/projects?cursor=${pageParam}`)
|
||||
return await response.json()
|
||||
},
|
||||
initialPageParam: 0,
|
||||
getPreviousPageParam: (firstPage) => firstPage.previousId ?? undefined,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId ?? undefined,
|
||||
maxPages: 3,
|
||||
})
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended
|
||||
- [x] 🔧 Fixable
|
||||
73
docs/eslint/mutation-property-order.md
Normal file
73
docs/eslint/mutation-property-order.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
id: mutation-property-order
|
||||
title: Ensure correct order of inference-sensitive properties in useMutation()
|
||||
---
|
||||
|
||||
For the following functions, the property order of the passed in object matters due to type inference:
|
||||
|
||||
- `useMutation()`
|
||||
|
||||
The correct property order is as follows:
|
||||
|
||||
- `onMutate`
|
||||
- `onError`
|
||||
- `onSettled`
|
||||
|
||||
All other properties are insensitive to the order as they do not depend on type inference.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/mutation-property-order": "warn" */
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: () => Promise.resolve('success'),
|
||||
onSettled: () => {
|
||||
results.push('onSettled-promise')
|
||||
return Promise.resolve('also-ignored') // Promise<string> (should be ignored)
|
||||
},
|
||||
onMutate: async () => {
|
||||
results.push('onMutate-async')
|
||||
await sleep(1)
|
||||
return { backup: 'async-data' }
|
||||
},
|
||||
onError: async () => {
|
||||
results.push('onError-async-start')
|
||||
await sleep(1)
|
||||
results.push('onError-async-end')
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/mutation-property-order": "warn" */
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: () => Promise.resolve('success'),
|
||||
onMutate: async () => {
|
||||
results.push('onMutate-async')
|
||||
await sleep(1)
|
||||
return { backup: 'async-data' }
|
||||
},
|
||||
onError: async () => {
|
||||
results.push('onError-async-start')
|
||||
await sleep(1)
|
||||
results.push('onError-async-end')
|
||||
},
|
||||
onSettled: () => {
|
||||
results.push('onSettled-promise')
|
||||
return Promise.resolve('also-ignored') // Promise<string> (should be ignored)
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended
|
||||
- [x] 🔧 Fixable
|
||||
47
docs/eslint/no-rest-destructuring.md
Normal file
47
docs/eslint/no-rest-destructuring.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: no-rest-destructuring
|
||||
title: Disallow object rest destructuring on query results
|
||||
---
|
||||
|
||||
Use object rest destructuring on query results automatically subscribes to every field of the query result, which may cause unnecessary re-renders.
|
||||
This makes sure that you only subscribe to the fields that you actually need.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/no-rest-destructuring": "warn" */
|
||||
|
||||
const useTodos = () => {
|
||||
const { data: todos, ...rest } = useQuery({
|
||||
queryKey: ['todos'],
|
||||
queryFn: () => api.getTodos(),
|
||||
})
|
||||
return { todos, ...rest }
|
||||
}
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
const todosQuery = useQuery({
|
||||
queryKey: ['todos'],
|
||||
queryFn: () => api.getTodos(),
|
||||
})
|
||||
|
||||
// normal object destructuring is fine
|
||||
const { data: todos } = todosQuery
|
||||
```
|
||||
|
||||
When [typed linting](https://typescript-eslint.io/getting-started/typed-linting/) is enabled, the rule also flags rest destructuring on custom hooks that return a TanStack Query result.
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If you set the `notifyOnChangeProps` options manually, you can disable this rule.
|
||||
Since you are not using tracked queries, you are responsible for specifying which props should trigger a re-render.
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended
|
||||
- [ ] 🔧 Fixable
|
||||
56
docs/eslint/no-unstable-deps.md
Normal file
56
docs/eslint/no-unstable-deps.md
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: no-unstable-deps
|
||||
title: Disallow putting the result of query hooks directly in a React hook dependency array
|
||||
---
|
||||
|
||||
The object returned from the following query hooks is **not** referentially stable:
|
||||
|
||||
- `useQuery`
|
||||
- `useSuspenseQuery`
|
||||
- `useQueries`
|
||||
- `useSuspenseQueries`
|
||||
- `useInfiniteQuery`
|
||||
- `useSuspenseInfiniteQuery`
|
||||
- `useMutation`
|
||||
|
||||
The object returned from those hooks should **not** be put directly into the dependency array of a React hook (e.g. `useEffect`, `useMemo`, `useCallback`).
|
||||
Instead, destructure the return value of the query hook and pass the destructured values into the dependency array of the React hook.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/no-unstable-deps": "warn" */
|
||||
import { useCallback } from 'react'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
|
||||
function Component() {
|
||||
const mutation = useMutation({ mutationFn: (value: string) => value })
|
||||
const callback = useCallback(() => {
|
||||
mutation.mutate('hello')
|
||||
}, [mutation])
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/no-unstable-deps": "warn" */
|
||||
import { useCallback } from 'react'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
|
||||
function Component() {
|
||||
const { mutate } = useMutation({ mutationFn: (value: string) => value })
|
||||
const callback = useCallback(() => {
|
||||
mutate('hello')
|
||||
}, [mutate])
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended
|
||||
- [ ] 🔧 Fixable
|
||||
39
docs/eslint/no-void-query-fn.md
Normal file
39
docs/eslint/no-void-query-fn.md
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: no-void-query-fn
|
||||
title: Disallow returning void from query functions
|
||||
---
|
||||
|
||||
Query functions must return a value that will be cached by TanStack Query. Functions that don't return a value (void functions) can lead to unexpected behavior and might indicate a mistake in the implementation.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Example of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/no-void-query-fn": "error" */
|
||||
|
||||
useQuery({
|
||||
queryKey: ['todos'],
|
||||
queryFn: async () => {
|
||||
await api.todos.fetch() // Function doesn't return the fetched data
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Example of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/no-void-query-fn": "error" */
|
||||
useQuery({
|
||||
queryKey: ['todos'],
|
||||
queryFn: async () => {
|
||||
const todos = await api.todos.fetch()
|
||||
return todos
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended
|
||||
- [ ] 🔧 Fixable
|
||||
145
docs/eslint/prefer-query-options.md
Normal file
145
docs/eslint/prefer-query-options.md
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
id: prefer-query-options
|
||||
title: Prefer the use of queryOptions
|
||||
---
|
||||
|
||||
Separating `queryKey` and `queryFn` can cause unexpected runtime issues when the same query key is accidentally used with more than one `queryFn`. Wrapping them in `queryOptions` (or `infiniteQueryOptions`) co-locates the key and function, making queries safer and easier to reuse.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function Component({ id }) {
|
||||
const query = useQuery({
|
||||
queryKey: ['get', id],
|
||||
queryFn: () => Api.get(`/foo/${id}`),
|
||||
})
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function useFooQuery(id) {
|
||||
return useQuery({
|
||||
queryKey: ['get', id],
|
||||
queryFn: () => Api.get(`/foo/${id}`),
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function getFooOptions(id) {
|
||||
return queryOptions({
|
||||
queryKey: ['get', id],
|
||||
queryFn: () => Api.get(`/foo/${id}`),
|
||||
})
|
||||
}
|
||||
|
||||
function Component({ id }) {
|
||||
const query = useQuery(getFooOptions(id))
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function getFooOptions(id) {
|
||||
return queryOptions({
|
||||
queryKey: ['get', id],
|
||||
queryFn: () => Api.get(`/foo/${id}`),
|
||||
})
|
||||
}
|
||||
|
||||
function useFooQuery(id) {
|
||||
return useQuery({ ...getFooOptions(id), select: (data) => data.foo })
|
||||
}
|
||||
```
|
||||
|
||||
The rule also enforces reusing `queryKey` from a `queryOptions` result instead of typing it manually in `QueryClient` methods or filters.
|
||||
|
||||
Examples of **incorrect** `queryKey` references for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function todoOptions(id) {
|
||||
return queryOptions({
|
||||
queryKey: ['todo', id],
|
||||
queryFn: () => api.getTodo(id),
|
||||
})
|
||||
}
|
||||
|
||||
function Component({ id }) {
|
||||
const queryClient = useQueryClient()
|
||||
return queryClient.getQueryData(['todo', id])
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function todoOptions(id) {
|
||||
return queryOptions({
|
||||
queryKey: ['todo', id],
|
||||
queryFn: () => api.getTodo(id),
|
||||
})
|
||||
}
|
||||
|
||||
function Component({ id }) {
|
||||
const queryClient = useQueryClient()
|
||||
return queryClient.invalidateQueries({ queryKey: ['todo', id] })
|
||||
}
|
||||
```
|
||||
|
||||
Examples of **correct** `queryKey` references for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function todoOptions(id) {
|
||||
return queryOptions({
|
||||
queryKey: ['todo', id],
|
||||
queryFn: () => api.getTodo(id),
|
||||
})
|
||||
}
|
||||
|
||||
function Component({ id }) {
|
||||
const queryClient = useQueryClient()
|
||||
return queryClient.getQueryData(todoOptions(id).queryKey)
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/prefer-query-options": "error" */
|
||||
|
||||
function todoOptions(id) {
|
||||
return queryOptions({
|
||||
queryKey: ['todo', id],
|
||||
queryFn: () => api.getTodo(id),
|
||||
})
|
||||
}
|
||||
|
||||
function Component({ id }) {
|
||||
const queryClient = useQueryClient()
|
||||
return queryClient.invalidateQueries({ queryKey: todoOptions(id).queryKey })
|
||||
}
|
||||
```
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If you do not want to enforce the use of `queryOptions` in your codebase, you will not need this rule.
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended (strict)
|
||||
- [ ] 🔧 Fixable
|
||||
61
docs/eslint/stable-query-client.md
Normal file
61
docs/eslint/stable-query-client.md
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
id: stable-query-client
|
||||
title: Stable Query Client
|
||||
---
|
||||
|
||||
The QueryClient contains the QueryCache, so you'd only want to create one instance of the QueryClient for the lifecycle of your application - _not_ a new instance on every render.
|
||||
|
||||
> Exception: It's allowed to create a new QueryClient inside an async Server Component, because the async function is only called once on the server.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```tsx
|
||||
/* eslint "@tanstack/query/stable-query-client": "error" */
|
||||
|
||||
function App() {
|
||||
const queryClient = new QueryClient()
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Home />
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```tsx
|
||||
function App() {
|
||||
const [queryClient] = useState(() => new QueryClient())
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Home />
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
const queryClient = new QueryClient()
|
||||
function App() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Home />
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
async function App() {
|
||||
const queryClient = new QueryClient()
|
||||
await queryClient.query(options)
|
||||
}
|
||||
```
|
||||
|
||||
## Attributes
|
||||
|
||||
- [x] ✅ Recommended
|
||||
- [x] 🔧 Fixable
|
||||
Reference in New Issue
Block a user