diff --git a/docs/config.json b/docs/config.json index fb3b3cc5e8..4015be985e 100644 --- a/docs/config.json +++ b/docs/config.json @@ -126,14 +126,14 @@ "label": "Infinite Queries", "to": "guides/infinite-queries" }, - { - "label": "Placeholder Query Data", - "to": "guides/placeholder-query-data" - }, { "label": "Initial Query Data", "to": "guides/initial-query-data" }, + { + "label": "Placeholder Query Data", + "to": "guides/placeholder-query-data" + }, { "label": "Prefetching", "to": "guides/prefetching" diff --git a/docs/guides/dependent-queries.md b/docs/guides/dependent-queries.md index b5f3acebb2..746f975b9a 100644 --- a/docs/guides/dependent-queries.md +++ b/docs/guides/dependent-queries.md @@ -7,7 +7,10 @@ Dependent (or serial) queries depend on previous ones to finish before they can ```tsx // Get the user -const { data: user } = useQuery({ queryKey: ['user', email], queryFn: getUserByEmail }) +const { data: user } = useQuery({ + queryKey: ['user', email], + queryFn: getUserByEmail, +}) const userId = user?.id diff --git a/docs/guides/disabling-queries.md b/docs/guides/disabling-queries.md index 850f5d629f..756e3212bd 100644 --- a/docs/guides/disabling-queries.md +++ b/docs/guides/disabling-queries.md @@ -7,12 +7,10 @@ If you ever want to disable a query from automatically running, you can use the When `enabled` is `false`: -- If the query has cached data - - The query will be initialized in the `status === 'success'` or `isSuccess` state. -- If the query does not have cached data - - The query will start in the `status === 'loading'` and `fetchStatus === 'idle'` +- If the query has cached data, then the query will be initialized in the `status === 'success'` or `isSuccess` state. +- If the query does not have cached data, then the query will start in the `status === 'loading'` and `fetchStatus === 'idle'` state. - The query will not automatically fetch on mount. -- The query will not automatically refetch in the background +- The query will not automatically refetch in the background. - The query will ignore query client `invalidateQueries` and `refetchQueries` calls that would normally result in the query refetching. - `refetch` returned from `useQuery` can be used to manually trigger the query to fetch. diff --git a/docs/guides/filters.md b/docs/guides/filters.md index 2c967ae50e..1de642b603 100644 --- a/docs/guides/filters.md +++ b/docs/guides/filters.md @@ -55,7 +55,9 @@ await queryClient.isMutating() await queryClient.isMutating({ mutationKey: ["post"] }) // Filter mutations using a predicate function -await queryClient.isMutating({ predicate: (mutation) => mutation.options.variables?.id === 1 }) +await queryClient.isMutating({ + predicate: (mutation) => mutation.options.variables?.id === 1, +}) ``` A mutation filter object supports the following properties: diff --git a/docs/guides/initial-query-data.md b/docs/guides/initial-query-data.md index e152b5d007..4744cb1256 100644 --- a/docs/guides/initial-query-data.md +++ b/docs/guides/initial-query-data.md @@ -85,9 +85,7 @@ function Todos() { const result = useQuery({ queryKey: ['todos'], queryFn: () => fetch('/todos'), - initialData: () => { - return getExpensiveTodos() - }, + initialData: () => getExpensiveTodos(), }) } ``` diff --git a/docs/guides/optimistic-updates.md b/docs/guides/optimistic-updates.md index d4ca467e44..a8b96cabe8 100644 --- a/docs/guides/optimistic-updates.md +++ b/docs/guides/optimistic-updates.md @@ -16,7 +16,8 @@ useMutation({ mutationFn: updateTodo, // When mutate is called: onMutate: async newTodo => { - // Cancel any outgoing refetches (so they don't overwrite our optimistic update) + // Cancel any outgoing refetches + // (so they don't overwrite our optimistic update) await queryClient.cancelQueries({ queryKey: ['todos'] }) // Snapshot the previous value @@ -28,7 +29,8 @@ useMutation({ // Return a context object with the snapshotted value return { previousTodos } }, - // If the mutation fails, use the context returned from onMutate to roll back + // If the mutation fails, + // use the context returned from onMutate to roll back onError: (err, newTodo, context) => { queryClient.setQueryData(['todos'], context.previousTodos) }, @@ -46,7 +48,8 @@ useMutation({ mutationFn: updateTodo, // When mutate is called: onMutate: async newTodo => { - // Cancel any outgoing refetches (so they don't overwrite our optimistic update) + // Cancel any outgoing refetches + // (so they don't overwrite our optimistic update) await queryClient.cancelQueries({ queryKey: ['todos', newTodo.id] }) // Snapshot the previous value diff --git a/docs/guides/paginated-queries.md b/docs/guides/paginated-queries.md index eb4ae13758..e5a3acbbfc 100644 --- a/docs/guides/paginated-queries.md +++ b/docs/guides/paginated-queries.md @@ -6,7 +6,10 @@ title: Paginated / Lagged Queries Rendering paginated data is a very common UI pattern and in React Query, it "just works" by including the page information in the query key: ```tsx -const result = useQuery({ queryKey: ['projects', page], queryFn: fetchProjects }) +const result = useQuery({ + queryKey: ['projects', page], + queryFn: fetchProjects +}) ``` However, if you run this simple example, you might notice something strange: diff --git a/docs/guides/placeholder-query-data.md b/docs/guides/placeholder-query-data.md index 05a2df541d..0e985ce195 100644 --- a/docs/guides/placeholder-query-data.md +++ b/docs/guides/placeholder-query-data.md @@ -35,7 +35,11 @@ If the process for accessing a query's placeholder data is intensive or just not ```tsx function Todos() { const placeholderData = useMemo(() => generateFakeTodos(), []) - const result = useQuery({ queyKey: ['todos'], queryFn: () => fetch('/todos'), placeholderData }) + const result = useQuery({ + queyKey: ['todos'], + queryFn: () => fetch('/todos'), + placeholderData + }) } ``` @@ -49,7 +53,8 @@ function Todo({ blogPostId }) { queryKey: ['blogPost', blogPostId], queryFn: () => fetch(`/blogPosts/${blogPostId}`), placeholderData: () => { - // Use the smaller/preview version of the blogPost from the 'blogPosts' query as the placeholder data for this blogPost query + // Use the smaller/preview version of the blogPost from the 'blogPosts' + // query as the placeholder data for this blogPost query return queryClient .getQueryData(['blogPosts']) ?.find(d => d.id === blogPostId) diff --git a/docs/guides/queries.md b/docs/guides/queries.md index ba8a0bac41..abafbc643f 100644 --- a/docs/guides/queries.md +++ b/docs/guides/queries.md @@ -45,7 +45,10 @@ For **most** queries, it's usually sufficient to check for the `isLoading` state ```tsx function Todos() { - const { isLoading, isError, data, error } = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) + const { isLoading, isError, data, error } = useQuery({ + queryKey: ['todos'], + queryFn: fetchTodoList, + }) if (isLoading) { return Loading... @@ -70,7 +73,10 @@ If booleans aren't your thing, you can always use the `status` state as well: ```tsx function Todos() { - const { status, data, error } = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) + const { status, data, error } = useQuery({ + queryKey: ['todos'], + queryFn: fetchTodoList, + }) if (status === 'loading') { return Loading... diff --git a/docs/guides/query-cancellation.md b/docs/guides/query-cancellation.md index 143a4d5d88..49eb2b4591 100644 --- a/docs/guides/query-cancellation.md +++ b/docs/guides/query-cancellation.md @@ -111,9 +111,12 @@ An `AbortSignal` can be set in the client `request` method. ```tsx const client = new GraphQLClient(endpoint) -const query = useQuery({ queryKey: ['todos'], queryFn: ({ signal }) => { - client.request({ document: query, signal }) -}}) +const query = useQuery({ + queryKey: ['todos'], + queryFn: ({ signal }) => { + client.request({ document: query, signal }) + } +}) ``` ## Using `graphql-request` version less than v4.0.0 @@ -137,17 +140,24 @@ const query = useQuery({ You might want to cancel a query manually. For example, if the request takes a long time to finish, you can allow the user to click a cancel button to stop the request. To do this, you just need to call `queryClient.cancelQueries({ queryKey })`, which will cancel the query and revert it back to its previous state. If `promise.cancel` is available, or you have consumed the `signal` passed to the query function, React Query will additionally also cancel the Promise. ```tsx -const query = useQuery({ queryKey: ['todos'], queryFn: async ({ signal }) => { - const resp = await fetch('/todos', { signal }) - return resp.json() -}}) +const query = useQuery({ + queryKey: ['todos'], + queryFn: async ({ signal }) => { + const resp = await fetch('/todos', { signal }) + return resp.json() + } +}) const queryClient = useQueryClient() return ( - + ) ``` diff --git a/docs/guides/query-functions.md b/docs/guides/query-functions.md index e79ee67ad7..873ec025c1 100644 --- a/docs/guides/query-functions.md +++ b/docs/guides/query-functions.md @@ -14,7 +14,10 @@ useQuery({ queryKey: ['todos', todoId], queryFn: async () => { const data = await fetchTodoById(todoId) return data }}) -useQuery({ queryKey: ['todos', todoId], queryFn: ({ queryKey }) => fetchTodoById(queryKey[1])}) +useQuery({ + queryKey: ['todos', todoId], + queryFn: ({ queryKey }) => fetchTodoById(queryKey[1]), +}) ``` ## Handling and Throwing Errors @@ -60,7 +63,10 @@ Query keys are not just for uniquely identifying the data you are fetching, but ```tsx function Todos({ status, page }) { - const result = useQuery({ queryKey: ['todos', { status, page }], queryFn: fetchTodoList }) + const result = useQuery({ + queryKey: ['todos', { status, page }], + queryFn: fetchTodoList, + }) } // Access the key, status and page variables in your query function! diff --git a/docs/guides/query-invalidation.md b/docs/guides/query-invalidation.md index 9ca3a0c2a8..cbd1093e49 100644 --- a/docs/guides/query-invalidation.md +++ b/docs/guides/query-invalidation.md @@ -34,32 +34,55 @@ const queryClient = useQueryClient() queryClient.invalidateQueries({ queryKey: ['todos'] }) // Both queries below will be invalidated -const todoListQuery = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) -const todoListQuery = useQuery({ queryKey: ['todos', { page: 1 }], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos'], + queryFn: fetchTodoList, +}) +const todoListQuery = useQuery({ + queryKey: ['todos', { page: 1 }], + queryFn: fetchTodoList, +}) ``` You can even invalidate queries with specific variables by passing a more specific query key to the `invalidateQueries` method: ```tsx -queryClient.invalidateQueries({ queryKey: ['todos', { type: 'done' }]}) +queryClient.invalidateQueries({ + queryKey: ['todos', { type: 'done' }, +}) // The query below will be invalidated -const todoListQuery = useQuery({ queryKey: ['todos', { type: 'done' }], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos', { type: 'done' }], + queryFn: fetchTodoList, +}) // However, the following query below will NOT be invalidated -const todoListQuery = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos'], + queryFn: fetchTodoList, +}) ``` The `invalidateQueries` API is very flexible, so even if you want to **only** invalidate `todos` queries that don't have any more variables or subkeys, you can pass an `exact: true` option to the `invalidateQueries` method: ```tsx -queryClient.invalidateQueries({ queryKey: ['todos'], exact: true }) +queryClient.invalidateQueries({ + queryKey: ['todos'], + exact: true, +}) // The query below will be invalidated -const todoListQuery = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos'], + queryFn: fetchTodoList, +}) // However, the following query below will NOT be invalidated -const todoListQuery = useQuery({ queryKey: ['todos', { type: 'done' }], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos', { type: 'done' }], + queryFn: fetchTodoList, +}) ``` If you find yourself wanting **even more** granularity, you can pass a predicate function to the `invalidateQueries` method. This function will receive each `Query` instance from the query cache and allow you to return `true` or `false` for whether you want to invalidate that query: @@ -71,11 +94,20 @@ queryClient.invalidateQueries({ }) // The query below will be invalidated -const todoListQuery = useQuery({ queryKey: ['todos', { version: 20 }], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos', { version: 20 }], + queryFn: fetchTodoList, +}), // The query below will be invalidated -const todoListQuery = useQuery({ queryKey: ['todos', { version: 10 }], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos', { version: 10 }], + queryFn: fetchTodoList, +}), // However, the following query below will NOT be invalidated -const todoListQuery = useQuery({ queryKey: ['todos', { version: 5 }], queryFn: fetchTodoList }) +const todoListQuery = useQuery({ + queryKey: ['todos', { version: 5 }], + queryFn: fetchTodoList, +}), ``` diff --git a/docs/guides/query-keys.md b/docs/guides/query-keys.md index 556075a076..7e800c0bf6 100644 --- a/docs/guides/query-keys.md +++ b/docs/guides/query-keys.md @@ -64,7 +64,10 @@ Since query keys uniquely describe the data they are fetching, they should inclu ```tsx function Todos({ todoId }) { - const result = useQuery({ queryKey: ['todos', todoId], queryFn: () => fetchTodoById(todoId) }) + const result = useQuery({ + queryKey: ['todos', todoId], + queryFn: () => fetchTodoById(todoId), + }) } ``` diff --git a/docs/guides/ssr.md b/docs/guides/ssr.md index 545d8c62b4..b993408ac9 100644 --- a/docs/guides/ssr.md +++ b/docs/guides/ssr.md @@ -31,7 +31,11 @@ export async function getStaticProps() { } function Posts(props) { - const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts, initialData: props.posts }) + const { data } = useQuery({ + queryKey: ['posts'], + queryFn: getPosts, + initialData: props.posts, + }) // ... } diff --git a/docs/guides/testing.md b/docs/guides/testing.md index 5da79f908f..8c983ac19a 100644 --- a/docs/guides/testing.md +++ b/docs/guides/testing.md @@ -114,7 +114,10 @@ Given the following custom hook: ```ts function useFetchData() { - return useQuery({ queryKey: ['fetchData'], queryFn: () => request('/api/data') }); + return useQuery({ + queryKey: ['fetchData'], + queryFn: () => request('/api/data'), + }); } ``` @@ -178,7 +181,10 @@ const expectation = nock('http://example.com') Now we can safely run our tests, the trick here is to await for the data assertion to pass: ```ts -const { result, waitFor } = renderHook(() => useInfiniteQueryCustomHook(), { wrapper }); +const { result, waitFor } = renderHook( + () => useInfiniteQueryCustomHook(), + { wrapper }, +); await waitFor(() => result.current.isSuccess); diff --git a/docs/guides/updates-from-mutation-responses.md b/docs/guides/updates-from-mutation-responses.md index b588c0e15b..6c22edb108 100644 --- a/docs/guides/updates-from-mutation-responses.md +++ b/docs/guides/updates-from-mutation-responses.md @@ -22,7 +22,10 @@ mutation.mutate({ // The query below will be updated with the response from the // successful mutation -const { status, data, error } = useQuery({ queryKey: ['todo', { id: 5 }], queryFn: fetchTodoById }) +const { status, data, error } = useQuery({ + queryKey: ['todo', { id: 5 }], + queryFn: fetchTodoById, +}) ``` You might want to tie the `onSuccess` logic into a reusable mutation, for that you can diff --git a/docs/guides/window-focus-refetching.md b/docs/guides/window-focus-refetching.md index ae24f7b0ff..22a25106be 100644 --- a/docs/guides/window-focus-refetching.md +++ b/docs/guides/window-focus-refetching.md @@ -25,7 +25,11 @@ function App() { #### Disabling Per-Query ```tsx -useQuery({ queryKey: ['todos'], queryFn: fetchTodos, refetchOnWindowFocus: false }) +useQuery({ + queryKey: ['todos'], + queryFn: fetchTodos, + refetchOnWindowFocus: false, +}) ``` ## Custom Window Focus Event diff --git a/docs/typescript.md b/docs/typescript.md index 7635655c35..6b67741cd8 100644 --- a/docs/typescript.md +++ b/docs/typescript.md @@ -17,15 +17,22 @@ Things to keep in mind: Types in React Query generally flow through very well so that you don't have to provide type annotations for yourself ```ts -const { data } = useQuery({ queryKey: ['test'], queryFn: () => Promise.resolve(5) }) +const { data } = useQuery({ // ^? const data: number | undefined + queryKey: ['test'], + queryFn: () => Promise.resolve(5) +}) ``` [typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAORToCGAxjALQCOO+VAsAFC8MQAdqnhIAJnRh0icALwoM2XHgAUAbSqDkIAEa4qAXQA0cFQEo5APjgAFciGAYAdLVQQANgDd0KgKxmzXgB6ILgw8IA9AH5eIA) ```ts -const { data } = useQuery({ queryKey: ['test'], queryFn: () => Promise.resolve(5), select: data => data.toString()}) +const { data } = useQuery({ // ^? const data: string | undefined + queryKey: ['test'], + queryFn: () => Promise.resolve(5), + select: data => data.toString(), +}) ``` [typescript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgVwM4FMCKz1QJ5wC+cAZlBCHAORToCGAxjALQCOO+VAsAFC8MQAdqnhIAJnRh0icALwoM2XHgAUAbSox0IqgF0ANHBUBKOQD44ABXIhgGAHS1UEADYA3dCoCsxw0gwu6EwAXHASUuZhknT2MBAAyjBQwIIA5iaExrwA9Nlw+QUAegD8vEA) @@ -46,7 +53,10 @@ const { data } = useQuery({ queryKey: ['groups'], queryFn: fetchGroups }) React Query uses a [discriminated union type](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions) for the query result, discriminated by the `status` field and the derived status boolean flags. This will allow you to check for e.g. `success` status to make `data` defined: ```ts -const { data, isSuccess } = useQuery({ queryKey: ['test'], queryFn: () => Promise.resolve(5) }) +const { data, isSuccess } = useQuery({ + queryKey: ['test'], + queryFn: () => Promise.resolve(5), +}) if (isSuccess) { data diff --git a/examples/react/optimistic-updates-typescript/pages/index.tsx b/examples/react/optimistic-updates-typescript/pages/index.tsx index 7e313d37d9..fb407cd4d7 100755 --- a/examples/react/optimistic-updates-typescript/pages/index.tsx +++ b/examples/react/optimistic-updates-typescript/pages/index.tsx @@ -40,7 +40,8 @@ function Example() { // When mutate is called: onMutate: async (newTodo: string) => { setText('') - // Cancel any outgoing refetches (so they don't overwrite our optimistic update) + // Cancel any outgoing refetches + // (so they don't overwrite our optimistic update) await queryClient.cancelQueries(['todos']) // Snapshot the previous value @@ -59,7 +60,8 @@ function Example() { return { previousTodos } }, - // If the mutation fails, use the context returned from onMutate to roll back + // If the mutation fails, + // use the context returned from onMutate to roll back onError: (err, variables, context) => { if (context?.previousTodos) { queryClient.setQueryData(['todos'], context.previousTodos)