diff --git a/examples/react/algolia/.prettierrc b/examples/react/algolia/.prettierrc deleted file mode 100644 index 0967ef424b..0000000000 --- a/examples/react/algolia/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/examples/react/algolia/package.json b/examples/react/algolia/package.json index e2dc6611ae..5125164887 100644 --- a/examples/react/algolia/package.json +++ b/examples/react/algolia/package.json @@ -12,15 +12,15 @@ "@algolia/transporter": "4.17.1", "@tanstack/react-query": "^5.0.0-alpha.38", "@tanstack/react-query-devtools": "^5.0.0-alpha.38", - "algoliasearch": "4.17.1" + "algoliasearch": "4.17.1", + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.0.0-alpha.36", "@types/react": "^18.2.4", "@types/react-dom": "^18.2.4", "@vitejs/plugin-react": "^4.0.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", "typescript": "^5.0.4", "vite": "^4.2.0" }, diff --git a/examples/react/algolia/src/App.tsx b/examples/react/algolia/src/App.tsx index 6770f42445..039e66024e 100644 --- a/examples/react/algolia/src/App.tsx +++ b/examples/react/algolia/src/App.tsx @@ -1,9 +1,9 @@ -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import "./styles.css"; -import Search from "./Search"; +import './styles.css' +import Search from './Search' -const queryClient = new QueryClient(); +const queryClient = new QueryClient() export default function App() { return ( @@ -13,5 +13,5 @@ export default function App() { - ); + ) } diff --git a/examples/react/algolia/src/Search.tsx b/examples/react/algolia/src/Search.tsx index 1e9f97dcc9..3755abe5a9 100644 --- a/examples/react/algolia/src/Search.tsx +++ b/examples/react/algolia/src/Search.tsx @@ -1,15 +1,15 @@ -import { useState } from "react"; +import { useState } from 'react' -import SearchResults from "./SearchResults"; +import SearchResults from './SearchResults' export default function Search() { - const [query, setQuery] = useState(""); + const [query, setQuery] = useState('') const handleOnChange = (event: React.ChangeEvent) => { - event.preventDefault(); + event.preventDefault() // It is recommended to debounce this event in prod - setQuery(event.target.value); - }; + setQuery(event.target.value) + } return (
@@ -20,5 +20,5 @@ export default function Search() { />
- ); + ) } diff --git a/examples/react/algolia/src/SearchResults.tsx b/examples/react/algolia/src/SearchResults.tsx index d03fb303d8..59b353a7dd 100644 --- a/examples/react/algolia/src/SearchResults.tsx +++ b/examples/react/algolia/src/SearchResults.tsx @@ -1,16 +1,16 @@ -import useAlgolia from "./useAlgolia"; +import useAlgolia from './useAlgolia' type Product = { - name: string; - shortDescription: string; - salePrice: number; -}; + name: string + shortDescription: string + salePrice: number +} type SearchResultsProps = { - query: string; -}; + query: string +} -export default function SearchResults({ query = "" }: SearchResultsProps) { +export default function SearchResults({ query = '' }: SearchResultsProps) { const { hits, isLoading, @@ -20,17 +20,17 @@ export default function SearchResults({ query = "" }: SearchResultsProps) { isFetchingNextPage, fetchNextPage, } = useAlgolia({ - indexName: "bestbuy", + indexName: 'bestbuy', query, hitsPerPage: 5, staleTime: 1000 * 30, // 30s gcTime: 1000 * 60 * 15, // 15m enabled: !!query, - }); + }) - if (!query) return null; + if (!query) return null - if (isLoading) return
Loading...
; + if (isLoading) return
Loading...
return (
@@ -69,5 +69,5 @@ export default function SearchResults({ query = "" }: SearchResultsProps) { )}
- ); + ) } diff --git a/examples/react/algolia/src/algolia.ts b/examples/react/algolia/src/algolia.ts index 6cc1ef4972..bc816ac104 100644 --- a/examples/react/algolia/src/algolia.ts +++ b/examples/react/algolia/src/algolia.ts @@ -1,17 +1,17 @@ -import algoliasearch from "algoliasearch"; -import { Hit } from "@algolia/client-search"; +import algoliasearch from 'algoliasearch' +import { Hit } from '@algolia/client-search' // From Algolia example // https://github.com/algolia/react-instantsearch -const ALGOLIA_APP_ID = "latency"; -const ALGOLIA_SEARCH_API_KEY = "6be0576ff61c053d5f9a3225e2a90f76"; +const ALGOLIA_APP_ID = 'latency' +const ALGOLIA_SEARCH_API_KEY = '6be0576ff61c053d5f9a3225e2a90f76' type SearchOptions = { - indexName: string; - query: string; - pageParam: number; - hitsPerPage: number; -}; + indexName: string + query: string + pageParam: number + hitsPerPage: number +} export async function search({ indexName, @@ -19,20 +19,20 @@ export async function search({ pageParam, hitsPerPage = 10, }: SearchOptions): Promise<{ - hits: Hit[]; - nextPage: number | undefined; + hits: Hit[] + nextPage: number | undefined }> { - const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY); - const index = client.initIndex(indexName); + const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY) + const index = client.initIndex(indexName) - console.log("alogolia:search", { indexName, query, pageParam, hitsPerPage }); + console.log('alogolia:search', { indexName, query, pageParam, hitsPerPage }) const { hits, page, nbPages } = await index.search(query, { page: pageParam, hitsPerPage, - }); + }) - const nextPage = page + 1 < nbPages ? page + 1 : undefined; + const nextPage = page + 1 < nbPages ? page + 1 : undefined - return { hits, nextPage }; + return { hits, nextPage } } diff --git a/examples/react/algolia/src/index.tsx b/examples/react/algolia/src/index.tsx index 7fabc9c5c9..5580576a6b 100644 --- a/examples/react/algolia/src/index.tsx +++ b/examples/react/algolia/src/index.tsx @@ -1,6 +1,6 @@ -import ReactDOM from "react-dom/client"; +import ReactDOM from 'react-dom/client' -import App from "./App"; +import App from './App' -const rootElement = document.getElementById("root") as HTMLElement; -ReactDOM.createRoot(rootElement).render(); +const rootElement = document.getElementById('root') as HTMLElement +ReactDOM.createRoot(rootElement).render() diff --git a/examples/react/algolia/src/useAlgolia.ts b/examples/react/algolia/src/useAlgolia.ts index 61f23ffdda..a47b96577d 100644 --- a/examples/react/algolia/src/useAlgolia.ts +++ b/examples/react/algolia/src/useAlgolia.ts @@ -1,14 +1,14 @@ -import { useInfiniteQuery } from "@tanstack/react-query"; -import { search } from "./algolia"; +import { useInfiniteQuery } from '@tanstack/react-query' +import { search } from './algolia' export type UseAlgoliaOptions = { - indexName: string; - query: string; - hitsPerPage?: number; - staleTime?: number; - gcTime?: number; - enabled?: boolean; -}; + indexName: string + query: string + hitsPerPage?: number + staleTime?: number + gcTime?: number + enabled?: boolean +} export default function useAlgolia({ indexName, @@ -19,7 +19,7 @@ export default function useAlgolia({ enabled, }: UseAlgoliaOptions) { const queryInfo = useInfiniteQuery({ - queryKey: ["algolia", indexName, query, hitsPerPage], + queryKey: ['algolia', indexName, query, hitsPerPage], queryFn: ({ pageParam }) => search({ indexName, query, pageParam, hitsPerPage }), defaultPageParam: 0, @@ -27,9 +27,9 @@ export default function useAlgolia({ staleTime, gcTime, enabled, - }); + }) - const hits = queryInfo.data?.pages.map((page) => page.hits).flat(); + const hits = queryInfo.data?.pages.map((page) => page.hits).flat() - return { ...queryInfo, hits }; + return { ...queryInfo, hits } } diff --git a/examples/react/algolia/vite.config.js b/examples/react/algolia/vite.config.js index 081c8d9f69..9ffcc67574 100644 --- a/examples/react/algolia/vite.config.js +++ b/examples/react/algolia/vite.config.js @@ -1,6 +1,6 @@ -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], -}); +}) diff --git a/examples/react/auto-refetching/pages/api/data.js b/examples/react/auto-refetching/src/pages/api/data.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/auto-refetching/pages/api/data.js rename to examples/react/auto-refetching/src/pages/api/data.js diff --git a/examples/react/auto-refetching/pages/index.js b/examples/react/auto-refetching/src/pages/index.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/auto-refetching/pages/index.js rename to examples/react/auto-refetching/src/pages/index.js diff --git a/examples/react/basic-graphql-request/.prettierrc b/examples/react/basic-graphql-request/.prettierrc deleted file mode 100644 index 0967ef424b..0000000000 --- a/examples/react/basic-graphql-request/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/examples/react/basic-graphql-request/src/index.jsx b/examples/react/basic-graphql-request/src/index.jsx index 30a45cfa66..b484d73a23 100644 --- a/examples/react/basic-graphql-request/src/index.jsx +++ b/examples/react/basic-graphql-request/src/index.jsx @@ -1,21 +1,21 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ -import React from "react"; -import ReactDOM from "react-dom/client"; +import React from 'react' +import ReactDOM from 'react-dom/client' import { useQuery, useQueryClient, QueryClient, QueryClientProvider, -} from "@tanstack/react-query"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; -import { request, gql } from "graphql-request"; +} from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { request, gql } from 'graphql-request' -const endpoint = "https://graphqlzero.almansi.me/api"; +const endpoint = 'https://graphqlzero.almansi.me/api' -const queryClient = new QueryClient(); +const queryClient = new QueryClient() function App() { - const [postId, setPostId] = React.useState(-1); + const [postId, setPostId] = React.useState(-1) return ( @@ -23,7 +23,7 @@ function App() { As you visit the posts below, you will notice them in a loading state the first time you load them. However, after you return to this list and click on any posts you have already visited again, you will see them - load instantly and background refresh right before your eyes!{" "} + load instantly and background refresh right before your eyes!{' '} (You may need to throttle your network speed to simulate longer loading sequences) @@ -36,12 +36,12 @@ function App() { )} - ); + ) } function usePosts() { return useQuery({ - queryKey: ["posts"], + queryKey: ['posts'], queryFn: async () => { const { posts: { data }, @@ -56,24 +56,24 @@ function usePosts() { } } } - ` - ); - return data; + `, + ) + return data }, - }); + }) } function Posts({ setPostId }) { - const queryClient = useQueryClient(); - const { status, data, error, isFetching } = usePosts(); + const queryClient = useQueryClient() + const { status, data, error, isFetching } = usePosts() return (

Posts

- {status === "pending" ? ( - "Loading..." - ) : status === "error" ? ( + {status === 'pending' ? ( + 'Loading...' + ) : status === 'error' ? ( Error: {error.message} ) : ( <> @@ -86,10 +86,10 @@ function Posts({ setPostId }) { style={ // We can find the existing query data here to show bold links for // ones that are cached - queryClient.getQueryData(["post", post.id]) + queryClient.getQueryData(['post', post.id]) ? { - fontWeight: "bold", - color: "green", + fontWeight: 'bold', + color: 'green', } : {} } @@ -99,17 +99,17 @@ function Posts({ setPostId }) {

))}
-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)}
- ); + ) } function usePost(postId) { return useQuery( - ["post", postId], + ['post', postId], async () => { const { post } = await request( endpoint, @@ -121,19 +121,19 @@ function usePost(postId) { body } } - ` - ); + `, + ) - return post; + return post }, { enabled: !!postId, - } - ); + }, + ) } function Post({ postId, setPostId }) { - const { status, data, error, isFetching } = usePost(postId); + const { status, data, error, isFetching } = usePost(postId) return (
@@ -142,9 +142,9 @@ function Post({ postId, setPostId }) { Back
- {!postId || status === "pending" ? ( - "Loading..." - ) : status === "error" ? ( + {!postId || status === 'pending' ? ( + 'Loading...' + ) : status === 'error' ? ( Error: {error.message} ) : ( <> @@ -152,12 +152,12 @@ function Post({ postId, setPostId }) {

{data.body}

-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)} - ); + ) } -const rootElement = document.getElementById("root"); -ReactDOM.createRoot(rootElement).render(); +const rootElement = document.getElementById('root') +ReactDOM.createRoot(rootElement).render() diff --git a/examples/react/basic-typescript/.prettierrc b/examples/react/basic-typescript/.prettierrc deleted file mode 100644 index 0967ef424b..0000000000 --- a/examples/react/basic-typescript/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/examples/react/basic-typescript/src/index.tsx b/examples/react/basic-typescript/src/index.tsx index 260303483a..34b931bbc4 100644 --- a/examples/react/basic-typescript/src/index.tsx +++ b/examples/react/basic-typescript/src/index.tsx @@ -1,11 +1,11 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ -import * as React from "react"; -import ReactDOM from "react-dom/client"; -import axios from "axios"; -import { useQuery, useQueryClient, QueryClient } from "@tanstack/react-query"; -import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client"; -import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +import * as React from 'react' +import ReactDOM from 'react-dom/client' +import axios from 'axios' +import { useQuery, useQueryClient, QueryClient } from '@tanstack/react-query' +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' +import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' const queryClient = new QueryClient({ defaultOptions: { @@ -13,44 +13,44 @@ const queryClient = new QueryClient({ gcTime: 1000 * 60 * 60 * 24, // 24 hours }, }, -}); +}) const persister = createSyncStoragePersister({ storage: window.localStorage, -}); +}) type Post = { - id: number; - title: string; - body: string; -}; + id: number + title: string + body: string +} function usePosts() { return useQuery({ - queryKey: ["posts"], + queryKey: ['posts'], queryFn: async (): Promise> => { const { data } = await axios.get( - "https://jsonplaceholder.typicode.com/posts" - ); - return data; + 'https://jsonplaceholder.typicode.com/posts', + ) + return data }, - }); + }) } function Posts({ setPostId, }: { - setPostId: React.Dispatch>; + setPostId: React.Dispatch> }) { - const queryClient = useQueryClient(); - const { status, data, error, isFetching } = usePosts(); + const queryClient = useQueryClient() + const { status, data, error, isFetching } = usePosts() return (

Posts

- {status === "pending" ? ( - "Loading..." + {status === 'pending' ? ( + 'Loading...' ) : error instanceof Error ? ( Error: {error.message} ) : ( @@ -64,10 +64,10 @@ function Posts({ style={ // We can access the query data here to show bold links for // ones that are cached - queryClient.getQueryData(["post", post.id]) + queryClient.getQueryData(['post', post.id]) ? { - fontWeight: "bold", - color: "green", + fontWeight: 'bold', + color: 'green', } : {} } @@ -77,37 +77,37 @@ function Posts({

))}
-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)}
- ); + ) } const getPostById = async (id: number): Promise => { const { data } = await axios.get( - `https://jsonplaceholder.typicode.com/posts/${id}` - ); - return data; -}; + `https://jsonplaceholder.typicode.com/posts/${id}`, + ) + return data +} function usePost(postId: number) { return useQuery({ - queryKey: ["post", postId], + queryKey: ['post', postId], queryFn: () => getPostById(postId), enabled: !!postId, - }); + }) } function Post({ postId, setPostId, }: { - postId: number; - setPostId: React.Dispatch>; + postId: number + setPostId: React.Dispatch> }) { - const { status, data, error, isFetching } = usePost(postId); + const { status, data, error, isFetching } = usePost(postId) return (
@@ -116,8 +116,8 @@ function Post({ Back
- {!postId || status === "pending" ? ( - "Loading..." + {!postId || status === 'pending' ? ( + 'Loading...' ) : error instanceof Error ? ( Error: {error.message} ) : ( @@ -126,15 +126,15 @@ function Post({

{data?.body}

-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)} - ); + ) } function App() { - const [postId, setPostId] = React.useState(-1); + const [postId, setPostId] = React.useState(-1) return ( (You may need to throttle your network speed to simulate longer loading sequences) @@ -158,8 +158,8 @@ function App() { )} - ); + ) } -const rootElement = document.getElementById("root") as HTMLElement; -ReactDOM.createRoot(rootElement).render(); +const rootElement = document.getElementById('root') as HTMLElement +ReactDOM.createRoot(rootElement).render() diff --git a/examples/react/basic-typescript/vite.config.ts b/examples/react/basic-typescript/vite.config.ts index 9cc50ead1c..5a33944a9b 100644 --- a/examples/react/basic-typescript/vite.config.ts +++ b/examples/react/basic-typescript/vite.config.ts @@ -1,7 +1,7 @@ -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], -}); +}) diff --git a/examples/react/basic/.prettierrc b/examples/react/basic/.prettierrc deleted file mode 100644 index 0967ef424b..0000000000 --- a/examples/react/basic/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/examples/react/basic/src/index.jsx b/examples/react/basic/src/index.jsx index 05590a9512..e038ea9b33 100644 --- a/examples/react/basic/src/index.jsx +++ b/examples/react/basic/src/index.jsx @@ -1,19 +1,19 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ -import React from "react"; -import ReactDOM from "react-dom/client"; -import axios from "axios"; +import React from 'react' +import ReactDOM from 'react-dom/client' +import axios from 'axios' import { useQuery, useQueryClient, QueryClient, QueryClientProvider, -} from "@tanstack/react-query"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +} from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' -const queryClient = new QueryClient(); +const queryClient = new QueryClient() function App() { - const [postId, setPostId] = React.useState(-1); + const [postId, setPostId] = React.useState(-1) return ( @@ -21,7 +21,7 @@ function App() { As you visit the posts below, you will notice them in a loading state the first time you load them. However, after you return to this list and click on any posts you have already visited again, you will see them - load instantly and background refresh right before your eyes!{" "} + load instantly and background refresh right before your eyes!{' '} (You may need to throttle your network speed to simulate longer loading sequences) @@ -34,32 +34,32 @@ function App() { )} - ); + ) } function usePosts() { return useQuery({ - queryKey: ["posts"], + queryKey: ['posts'], queryFn: async () => { const { data } = await axios.get( - "https://jsonplaceholder.typicode.com/posts" - ); - return data; + 'https://jsonplaceholder.typicode.com/posts', + ) + return data }, - }); + }) } function Posts({ setPostId }) { - const queryClient = useQueryClient(); - const { status, data, error, isFetching } = usePosts(); + const queryClient = useQueryClient() + const { status, data, error, isFetching } = usePosts() return (

Posts

- {status === "pending" ? ( - "Loading..." - ) : status === "error" ? ( + {status === 'pending' ? ( + 'Loading...' + ) : status === 'error' ? ( Error: {error.message} ) : ( <> @@ -72,10 +72,10 @@ function Posts({ setPostId }) { style={ // We can access the query data here to show bold links for // ones that are cached - queryClient.getQueryData(["post", post.id]) + queryClient.getQueryData(['post', post.id]) ? { - fontWeight: "bold", - color: "green", + fontWeight: 'bold', + color: 'green', } : {} } @@ -85,31 +85,31 @@ function Posts({ setPostId }) {

))}
-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)}
- ); + ) } const getPostById = async (id) => { const { data } = await axios.get( - `https://jsonplaceholder.typicode.com/posts/${id}` - ); - return data; -}; + `https://jsonplaceholder.typicode.com/posts/${id}`, + ) + return data +} function usePost(postId) { return useQuery({ - queryKey: ["post", postId], + queryKey: ['post', postId], queryFn: () => getPostById(postId), enabled: !!postId, - }); + }) } function Post({ postId, setPostId }) { - const { status, data, error, isFetching } = usePost(postId); + const { status, data, error, isFetching } = usePost(postId) return (
@@ -118,9 +118,9 @@ function Post({ postId, setPostId }) { Back
- {!postId || status === "pending" ? ( - "Loading..." - ) : status === "error" ? ( + {!postId || status === 'pending' ? ( + 'Loading...' + ) : status === 'error' ? ( Error: {error.message} ) : ( <> @@ -128,12 +128,12 @@ function Post({ postId, setPostId }) {

{data.body}

-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)} - ); + ) } -const rootElement = document.getElementById("root"); -ReactDOM.createRoot(rootElement).render(); +const rootElement = document.getElementById('root') +ReactDOM.createRoot(rootElement).render() diff --git a/examples/react/default-query-function/.prettierrc b/examples/react/default-query-function/.prettierrc deleted file mode 100644 index 0967ef424b..0000000000 --- a/examples/react/default-query-function/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/examples/react/default-query-function/package.json b/examples/react/default-query-function/package.json index dafb1d1e79..d21a3a06ee 100644 --- a/examples/react/default-query-function/package.json +++ b/examples/react/default-query-function/package.json @@ -8,11 +8,11 @@ "preview": "vite preview" }, "dependencies": { + "@tanstack/react-query": "^5.0.0-alpha.38", + "@tanstack/react-query-devtools": "^5.0.0-alpha.38", "axios": "^1.4.0", "react": "^18.2.0", - "react-dom": "^18.2.0", - "@tanstack/react-query": "^5.0.0-alpha.38", - "@tanstack/react-query-devtools": "^5.0.0-alpha.38" + "react-dom": "^18.2.0" }, "devDependencies": { "@vitejs/plugin-react": "^4.0.0", diff --git a/examples/react/default-query-function/src/index.jsx b/examples/react/default-query-function/src/index.jsx index 88fba6e3d7..5b494df68e 100644 --- a/examples/react/default-query-function/src/index.jsx +++ b/examples/react/default-query-function/src/index.jsx @@ -1,22 +1,22 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ -import React from "react"; -import ReactDOM from "react-dom/client"; -import axios from "axios"; +import React from 'react' +import ReactDOM from 'react-dom/client' +import axios from 'axios' import { useQuery, useQueryClient, QueryClient, QueryClientProvider, -} from "@tanstack/react-query"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +} from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' // Define a default query function that will receive the query key const defaultQueryFn = async ({ queryKey }) => { const { data } = await axios.get( - `https://jsonplaceholder.typicode.com${queryKey[0]}` - ); - return data; -}; + `https://jsonplaceholder.typicode.com${queryKey[0]}`, + ) + return data +} // provide the default query function to your app via the query client const queryClient = new QueryClient({ @@ -25,10 +25,10 @@ const queryClient = new QueryClient({ queryFn: defaultQueryFn, }, }, -}); +}) function App() { - const [postId, setPostId] = React.useState(-1); + const [postId, setPostId] = React.useState(-1) return ( @@ -36,7 +36,7 @@ function App() { As you visit the posts below, you will notice them in a loading state the first time you load them. However, after you return to this list and click on any posts you have already visited again, you will see them - load instantly and background refresh right before your eyes!{" "} + load instantly and background refresh right before your eyes!{' '} (You may need to throttle your network speed to simulate longer loading sequences) @@ -49,24 +49,24 @@ function App() { )} - ); + ) } function Posts({ setPostId }) { - const queryClient = useQueryClient(); + const queryClient = useQueryClient() // All you have to do now is pass a key! const { status, data, error, isFetching } = useQuery({ - queryKey: ["/posts"], - }); + queryKey: ['/posts'], + }) return (

Posts

- {status === "pending" ? ( - "Loading..." - ) : status === "error" ? ( + {status === 'pending' ? ( + 'Loading...' + ) : status === 'error' ? ( Error: {error.message} ) : ( <> @@ -79,10 +79,10 @@ function Posts({ setPostId }) { style={ // We can use the queryCache here to show bold links for // ones that are cached - queryClient.getQueryData(["post", post.id]) + queryClient.getQueryData(['post', post.id]) ? { - fontWeight: "bold", - color: "green", + fontWeight: 'bold', + color: 'green', } : {} } @@ -92,12 +92,12 @@ function Posts({ setPostId }) {

))}
-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)}
- ); + ) } function Post({ postId, setPostId }) { @@ -105,7 +105,7 @@ function Post({ postId, setPostId }) { const { status, data, error, isFetching } = useQuery({ queryKey: [`/posts/${postId}`], enabled: !!postId, - }); + }) return (
@@ -114,9 +114,9 @@ function Post({ postId, setPostId }) { Back
- {!postId || status === "pending" ? ( - "Loading..." - ) : status === "error" ? ( + {!postId || status === 'pending' ? ( + 'Loading...' + ) : status === 'error' ? ( Error: {error.message} ) : ( <> @@ -124,12 +124,12 @@ function Post({ postId, setPostId }) {

{data.body}

-
{isFetching ? "Background Updating..." : " "}
+
{isFetching ? 'Background Updating...' : ' '}
)} - ); + ) } -const rootElement = document.getElementById("root"); -ReactDOM.createRoot(rootElement).render(); +const rootElement = document.getElementById('root') +ReactDOM.createRoot(rootElement).render() diff --git a/examples/react/infinite-query-with-max-pages/pages/api/projects.js b/examples/react/infinite-query-with-max-pages/src/pages/api/projects.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/infinite-query-with-max-pages/pages/api/projects.js rename to examples/react/infinite-query-with-max-pages/src/pages/api/projects.js diff --git a/examples/react/infinite-query-with-max-pages/pages/index.js b/examples/react/infinite-query-with-max-pages/src/pages/index.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/infinite-query-with-max-pages/pages/index.js rename to examples/react/infinite-query-with-max-pages/src/pages/index.js diff --git a/examples/react/load-more-infinite-scroll/pages/about.js b/examples/react/load-more-infinite-scroll/src/pages/about.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/load-more-infinite-scroll/pages/about.js rename to examples/react/load-more-infinite-scroll/src/pages/about.js diff --git a/examples/react/load-more-infinite-scroll/pages/api/projects.js b/examples/react/load-more-infinite-scroll/src/pages/api/projects.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/load-more-infinite-scroll/pages/api/projects.js rename to examples/react/load-more-infinite-scroll/src/pages/api/projects.js diff --git a/examples/react/load-more-infinite-scroll/pages/index.js b/examples/react/load-more-infinite-scroll/src/pages/index.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/load-more-infinite-scroll/pages/index.js rename to examples/react/load-more-infinite-scroll/src/pages/index.js diff --git a/examples/react/nextjs/package.json b/examples/react/nextjs/package.json index 6e6e111b24..dc2da5f154 100644 --- a/examples/react/nextjs/package.json +++ b/examples/react/nextjs/package.json @@ -1,22 +1,21 @@ { "name": "@tanstack/query-example-react-nextjs", "version": "1.0.0", + "license": "MIT", "scripts": { "dev": "next", "build": "next build", "start": "next start" }, "dependencies": { + "@tanstack/react-query": "^5.0.0-alpha.38", + "@tanstack/react-query-devtools": "^5.0.0-alpha.38", "ky": "^0.33.3", "ky-universal": "^0.11.0", "next": "^13.4.4", "react": "^18.2.0", "react-dom": "^18.2.0", - "@tanstack/react-query": "^5.0.0-alpha.38", - "@tanstack/react-query-devtools": "^5.0.0-alpha.38", "resolve-from": "^5.0.0", "web-streams-polyfill": "^3.0.3" - }, - "license": "MIT", - "devDependencies": {} + } } diff --git a/examples/react/nextjs/components/Header/index.js b/examples/react/nextjs/src/components/Header/index.js similarity index 100% rename from examples/react/nextjs/components/Header/index.js rename to examples/react/nextjs/src/components/Header/index.js diff --git a/examples/react/nextjs/components/InfoBox/index.js b/examples/react/nextjs/src/components/InfoBox/index.js similarity index 100% rename from examples/react/nextjs/components/InfoBox/index.js rename to examples/react/nextjs/src/components/InfoBox/index.js diff --git a/examples/react/nextjs/components/Layout/index.js b/examples/react/nextjs/src/components/Layout/index.js similarity index 100% rename from examples/react/nextjs/components/Layout/index.js rename to examples/react/nextjs/src/components/Layout/index.js diff --git a/examples/react/nextjs/components/PostList/index.js b/examples/react/nextjs/src/components/PostList/index.js similarity index 100% rename from examples/react/nextjs/components/PostList/index.js rename to examples/react/nextjs/src/components/PostList/index.js diff --git a/examples/react/nextjs/components/index.js b/examples/react/nextjs/src/components/index.js similarity index 100% rename from examples/react/nextjs/components/index.js rename to examples/react/nextjs/src/components/index.js diff --git a/examples/react/nextjs/hooks/index.js b/examples/react/nextjs/src/hooks/index.js similarity index 100% rename from examples/react/nextjs/hooks/index.js rename to examples/react/nextjs/src/hooks/index.js diff --git a/examples/react/nextjs/hooks/usePosts/index.js b/examples/react/nextjs/src/hooks/usePosts/index.js similarity index 100% rename from examples/react/nextjs/hooks/usePosts/index.js rename to examples/react/nextjs/src/hooks/usePosts/index.js diff --git a/examples/react/nextjs/pages/_app.js b/examples/react/nextjs/src/pages/_app.js similarity index 100% rename from examples/react/nextjs/pages/_app.js rename to examples/react/nextjs/src/pages/_app.js diff --git a/examples/react/nextjs/pages/client-only.js b/examples/react/nextjs/src/pages/client-only.js similarity index 100% rename from examples/react/nextjs/pages/client-only.js rename to examples/react/nextjs/src/pages/client-only.js diff --git a/examples/react/nextjs/pages/index.js b/examples/react/nextjs/src/pages/index.js similarity index 100% rename from examples/react/nextjs/pages/index.js rename to examples/react/nextjs/src/pages/index.js diff --git a/examples/react/offline/.prettierrc b/examples/react/offline/.prettierrc deleted file mode 100644 index 0967ef424b..0000000000 --- a/examples/react/offline/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/examples/react/offline/package.json b/examples/react/offline/package.json index 654c91e247..0dcd59f4ab 100644 --- a/examples/react/offline/package.json +++ b/examples/react/offline/package.json @@ -9,15 +9,15 @@ }, "dependencies": { "@tanstack/react-location": "^3.7.0", + "@tanstack/react-query": "^5.0.0-alpha.38", + "@tanstack/react-query-devtools": "^5.0.0-alpha.38", + "@tanstack/react-query-persist-client": "^5.0.0-alpha.38", + "@tanstack/query-sync-storage-persister": "^5.0.0-alpha.38", "ky": "^0.33.3", "msw": "^0.39.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-hot-toast": "^2.4.1", - "@tanstack/react-query": "^5.0.0-alpha.38", - "@tanstack/react-query-devtools": "^5.0.0-alpha.38", - "@tanstack/react-query-persist-client": "^5.0.0-alpha.38", - "@tanstack/query-sync-storage-persister": "^5.0.0-alpha.38" + "react-hot-toast": "^2.4.1" }, "devDependencies": { "@vitejs/plugin-react": "^4.0.0", diff --git a/examples/react/offline/public/mockServiceWorker.js b/examples/react/offline/public/mockServiceWorker.js index ae4e96565b..ba0c013b83 100644 --- a/examples/react/offline/public/mockServiceWorker.js +++ b/examples/react/offline/public/mockServiceWorker.js @@ -8,118 +8,118 @@ * - Please do NOT serve this file on production. */ -const INTEGRITY_CHECKSUM = "02f4ad4a2797f85668baf196e553d929"; -const bypassHeaderName = "x-msw-bypass"; -const activeClientIds = new Set(); +const INTEGRITY_CHECKSUM = '02f4ad4a2797f85668baf196e553d929' +const bypassHeaderName = 'x-msw-bypass' +const activeClientIds = new Set() -self.addEventListener("install", function () { - return self.skipWaiting(); -}); +self.addEventListener('install', function () { + return self.skipWaiting() +}) -self.addEventListener("activate", async function (event) { - return self.clients.claim(); -}); +self.addEventListener('activate', async function (event) { + return self.clients.claim() +}) -self.addEventListener("message", async function (event) { - const clientId = event.source.id; +self.addEventListener('message', async function (event) { + const clientId = event.source.id if (!clientId || !self.clients) { - return; + return } - const client = await self.clients.get(clientId); + const client = await self.clients.get(clientId) if (!client) { - return; + return } - const allClients = await self.clients.matchAll(); + const allClients = await self.clients.matchAll() switch (event.data) { - case "KEEPALIVE_REQUEST": { + case 'KEEPALIVE_REQUEST': { sendToClient(client, { - type: "KEEPALIVE_RESPONSE", - }); - break; + type: 'KEEPALIVE_RESPONSE', + }) + break } - case "INTEGRITY_CHECK_REQUEST": { + case 'INTEGRITY_CHECK_REQUEST': { sendToClient(client, { - type: "INTEGRITY_CHECK_RESPONSE", + type: 'INTEGRITY_CHECK_RESPONSE', payload: INTEGRITY_CHECKSUM, - }); - break; + }) + break } - case "MOCK_ACTIVATE": { - activeClientIds.add(clientId); + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId) sendToClient(client, { - type: "MOCKING_ENABLED", + type: 'MOCKING_ENABLED', payload: true, - }); - break; + }) + break } - case "MOCK_DEACTIVATE": { - activeClientIds.delete(clientId); - break; + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId) + break } - case "CLIENT_CLOSED": { - activeClientIds.delete(clientId); + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId) const remainingClients = allClients.filter((client) => { - return client.id !== clientId; - }); + return client.id !== clientId + }) // Unregister itself when there are no more clients if (remainingClients.length === 0) { - self.registration.unregister(); + self.registration.unregister() } - break; + break } } -}); +}) // Resolve the "main" client for the given event. // Client that issues a request doesn't necessarily equal the client // that registered the worker. It's with the latter the worker should // communicate with during the response resolving phase. async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId); + const client = await self.clients.get(event.clientId) - if (client.frameType === "top-level") { - return client; + if (client.frameType === 'top-level') { + return client } - const allClients = await self.clients.matchAll(); + const allClients = await self.clients.matchAll() return allClients .filter((client) => { // Get only those clients that are currently visible. - return client.visibilityState === "visible"; + return client.visibilityState === 'visible' }) .find((client) => { // Find the client ID that's recorded in the // set of clients that have registered the worker. - return activeClientIds.has(client.id); - }); + return activeClientIds.has(client.id) + }) } async function handleRequest(event, requestId) { - const client = await resolveMainClient(event); - const response = await getResponse(event, client, requestId); + const client = await resolveMainClient(event) + const response = await getResponse(event, client, requestId) // Send back the response clone for the "response:*" life-cycle events. // Ensure MSW is active and ready to handle the message, otherwise // this message will pend indefinitely. if (client && activeClientIds.has(client.id)) { - (async function () { - const clonedResponse = response.clone(); + ;(async function () { + const clonedResponse = response.clone() sendToClient(client, { - type: "RESPONSE", + type: 'RESPONSE', payload: { requestId, type: clonedResponse.type, @@ -131,21 +131,21 @@ async function handleRequest(event, requestId) { headers: serializeHeaders(clonedResponse.headers), redirected: clonedResponse.redirected, }, - }); - })(); + }) + })() } - return response; + return response } async function getResponse(event, client, requestId) { - const { request } = event; - const requestClone = request.clone(); - const getOriginalResponse = () => fetch(requestClone); + const { request } = event + const requestClone = request.clone() + const getOriginalResponse = () => fetch(requestClone) // Bypass mocking when the request client is not active. if (!client) { - return getOriginalResponse(); + return getOriginalResponse() } // Bypass initial page load requests (i.e. static assets). @@ -153,29 +153,29 @@ async function getResponse(event, client, requestId) { // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet // and is not ready to handle requests. if (!activeClientIds.has(client.id)) { - return await getOriginalResponse(); + return await getOriginalResponse() } // Bypass requests with the explicit bypass header - if (requestClone.headers.get(bypassHeaderName) === "true") { - const cleanRequestHeaders = serializeHeaders(requestClone.headers); + if (requestClone.headers.get(bypassHeaderName) === 'true') { + const cleanRequestHeaders = serializeHeaders(requestClone.headers) // Remove the bypass header to comply with the CORS preflight check. - delete cleanRequestHeaders[bypassHeaderName]; + delete cleanRequestHeaders[bypassHeaderName] const originalRequest = new Request(requestClone, { headers: new Headers(cleanRequestHeaders), - }); + }) - return fetch(originalRequest); + return fetch(originalRequest) } // Send the request to the client-side MSW. - const reqHeaders = serializeHeaders(request.headers); - const body = await request.text(); + const reqHeaders = serializeHeaders(request.headers) + const body = await request.text() const clientMessage = await sendToClient(client, { - type: "REQUEST", + type: 'REQUEST', payload: { id: requestId, url: request.url, @@ -193,31 +193,31 @@ async function getResponse(event, client, requestId) { bodyUsed: request.bodyUsed, keepalive: request.keepalive, }, - }); + }) switch (clientMessage.type) { - case "MOCK_SUCCESS": { + case 'MOCK_SUCCESS': { return delayPromise( () => respondWithMock(clientMessage), - clientMessage.payload.delay - ); + clientMessage.payload.delay, + ) } - case "MOCK_NOT_FOUND": { - return getOriginalResponse(); + case 'MOCK_NOT_FOUND': { + return getOriginalResponse() } - case "NETWORK_ERROR": { - const { name, message } = clientMessage.payload; - const networkError = new Error(message); - networkError.name = name; + case 'NETWORK_ERROR': { + const { name, message } = clientMessage.payload + const networkError = new Error(message) + networkError.name = name // Rejecting a request Promise emulates a network error. - throw networkError; + throw networkError } - case "INTERNAL_ERROR": { - const parsedBody = JSON.parse(clientMessage.payload.body); + case 'INTERNAL_ERROR': { + const parsedBody = JSON.parse(clientMessage.payload.body) console.error( `\ @@ -228,54 +228,54 @@ ${parsedBody.location} This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\ `, request.method, - request.url - ); + request.url, + ) - return respondWithMock(clientMessage); + return respondWithMock(clientMessage) } } - return getOriginalResponse(); + return getOriginalResponse() } -self.addEventListener("fetch", function (event) { - const { request } = event; - const accept = request.headers.get("accept") || ""; +self.addEventListener('fetch', function (event) { + const { request } = event + const accept = request.headers.get('accept') || '' // Bypass server-sent events. - if (accept.includes("text/event-stream")) { - return; + if (accept.includes('text/event-stream')) { + return } // Bypass navigation requests. - if (request.mode === "navigate") { - return; + if (request.mode === 'navigate') { + return } // Opening the DevTools triggers the "only-if-cached" request // that cannot be handled by the worker. Bypass such requests. - if (request.cache === "only-if-cached" && request.mode !== "same-origin") { - return; + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + return } // Bypass all requests when there are no active clients. // Prevents the self-unregistered worked from handling requests // after it's been deleted (still remains active until the next reload). if (activeClientIds.size === 0) { - return; + return } - const requestId = uuidv4(); + const requestId = uuidv4() return event.respondWith( handleRequest(event, requestId).catch((error) => { - if (error.name === "NetworkError") { + if (error.name === 'NetworkError') { console.warn( '[MSW] Successfully emulated a network error for the "%s %s" request.', request.method, - request.url - ); - return; + request.url, + ) + return } // At this point, any exception indicates an issue with the original request/response. @@ -284,55 +284,55 @@ self.addEventListener("fetch", function (event) { [MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, request.method, request.url, - `${error.name}: ${error.message}` - ); - }) - ); -}); + `${error.name}: ${error.message}`, + ) + }), + ) +}) function serializeHeaders(headers) { - const reqHeaders = {}; + const reqHeaders = {} headers.forEach((value, name) => { reqHeaders[name] = reqHeaders[name] ? [].concat(reqHeaders[name]).concat(value) - : value; - }); - return reqHeaders; + : value + }) + return reqHeaders } function sendToClient(client, message) { return new Promise((resolve, reject) => { - const channel = new MessageChannel(); + const channel = new MessageChannel() channel.port1.onmessage = (event) => { if (event.data && event.data.error) { - return reject(event.data.error); + return reject(event.data.error) } - resolve(event.data); - }; + resolve(event.data) + } - client.postMessage(JSON.stringify(message), [channel.port2]); - }); + client.postMessage(JSON.stringify(message), [channel.port2]) + }) } function delayPromise(cb, duration) { return new Promise((resolve) => { - setTimeout(() => resolve(cb()), duration); - }); + setTimeout(() => resolve(cb()), duration) + }) } function respondWithMock(clientMessage) { return new Response(clientMessage.payload.body, { ...clientMessage.payload, headers: clientMessage.payload.headers, - }); + }) } function uuidv4() { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { - const r = (Math.random() * 16) | 0; - const v = c == "x" ? r : (r & 0x3) | 0x8; - return v.toString(16); - }); + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + const r = (Math.random() * 16) | 0 + const v = c == 'x' ? r : (r & 0x3) | 0x8 + return v.toString(16) + }) } diff --git a/examples/react/offline/src/App.jsx b/examples/react/offline/src/App.jsx index 3cd0aa9178..5e430e8187 100644 --- a/examples/react/offline/src/App.jsx +++ b/examples/react/offline/src/App.jsx @@ -1,4 +1,4 @@ -import * as React from "react"; +import * as React from 'react' import { useQuery, @@ -6,28 +6,28 @@ import { MutationCache, onlineManager, useIsRestoring, -} from "@tanstack/react-query"; -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; -import toast, { Toaster } from "react-hot-toast"; +} from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import toast, { Toaster } from 'react-hot-toast' -import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client"; -import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"; +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' +import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' import { Link, Outlet, ReactLocation, Router, useMatch, -} from "@tanstack/react-location"; +} from '@tanstack/react-location' -import * as api from "./api"; -import { movieKeys, useMovie } from "./movies"; +import * as api from './api' +import { movieKeys, useMovie } from './movies' const persister = createSyncStoragePersister({ storage: window.localStorage, -}); +}) -const location = new ReactLocation(); +const location = new ReactLocation() const queryClient = new QueryClient({ defaultOptions: { @@ -40,22 +40,22 @@ const queryClient = new QueryClient({ // configure global cache callbacks to show toast notifications mutationCache: new MutationCache({ onSuccess: (data) => { - toast.success(data.message); + toast.success(data.message) }, onError: (error) => { - toast.error(error.message); + toast.error(error.message) }, }), -}); +}) // we need a default mutation function so that paused mutations can resume after a page reload queryClient.setMutationDefaults(movieKeys.all(), { mutationFn: async ({ id, comment }) => { // to avoid clashes with our optimistic update when an offline mutation continues - await queryClient.cancelQueries({ queryKey: movieKeys.detail(id) }); - return api.updateMovie(id, comment); + await queryClient.cancelQueries({ queryKey: movieKeys.detail(id) }) + return api.updateMovie(id, comment) }, -}); +}) export default function App() { return ( @@ -65,28 +65,28 @@ export default function App() { onSuccess={() => { // resume mutations after initial restore from localStorage was successful queryClient.resumePausedMutations().then(() => { - queryClient.invalidateQueries(); - }); + queryClient.invalidateQueries() + }) }} > - ); + ) } function Movies() { - const isRestoring = useIsRestoring(); + const isRestoring = useIsRestoring() return ( , }, { - path: ":movieId", + path: ':movieId', element: , errorElement: , loader: ({ params: { movieId } }) => @@ -105,17 +105,17 @@ function Movies() { - ); + ) } function List() { const moviesQuery = useQuery({ queryKey: movieKeys.list(), queryFn: api.fetchMovies, - }); + }) if (moviesQuery.isLoading) { - return "Loading..."; + return 'Loading...' } if (moviesQuery.data) { @@ -139,17 +139,17 @@ function List() {
Updated at: {new Date(moviesQuery.data.ts).toLocaleTimeString()}
-
{moviesQuery.isFetching && "fetching..."}
+
{moviesQuery.isFetching && 'fetching...'}
- ); + ) } // query will be in 'idle' fetchStatus while restoring from localStorage - return null; + return null } function MovieError() { - const { error } = useMatch(); + const { error } = useMatch() return (
@@ -157,26 +157,26 @@ function MovieError() {

Couldn't load movie!

{error.message}
- ); + ) } function Detail() { const { params: { movieId }, - } = useMatch(); - const { comment, setComment, updateMovie, movieQuery } = useMovie(movieId); + } = useMatch() + const { comment, setComment, updateMovie, movieQuery } = useMovie(movieId) if (movieQuery.isLoading) { - return "Loading..."; + return 'Loading...' } function submitForm(event) { - event.preventDefault(); + event.preventDefault() updateMovie.mutate({ id: movieId, comment, - }); + }) } if (movieQuery.data) { @@ -207,19 +207,19 @@ function Detail() {
Updated at: {new Date(movieQuery.data.ts).toLocaleTimeString()}
-
{movieQuery.isFetching && "fetching..."}
+
{movieQuery.isFetching && 'fetching...'}
{updateMovie.isPaused - ? "mutation paused - offline" - : updateMovie.isPending && "updating..."} + ? 'mutation paused - offline' + : updateMovie.isPending && 'updating...'}
- ); + ) } if (movieQuery.isPaused) { - return "We're offline and have no data to show :("; + return "We're offline and have no data to show :(" } - return null; + return null } diff --git a/examples/react/offline/src/api.js b/examples/react/offline/src/api.js index 1bb7d0a9e0..582d56dbf3 100644 --- a/examples/react/offline/src/api.js +++ b/examples/react/offline/src/api.js @@ -1,41 +1,41 @@ -import { setupWorker, rest } from "msw"; -import ky from "ky"; +import { setupWorker, rest } from 'msw' +import ky from 'ky' const movies = [ { - id: "1", - title: "Guardians of the Galaxy", - comment: "", + id: '1', + title: 'Guardians of the Galaxy', + comment: '', }, { - id: "2", - title: "Wall-E", - comment: "", + id: '2', + title: 'Wall-E', + comment: '', }, -]; +] -export const fetchMovie = (id) => ky.get(`/movies/${id}`).json(); -export const fetchMovies = () => ky.get("/movies").json(); +export const fetchMovie = (id) => ky.get(`/movies/${id}`).json() +export const fetchMovies = () => ky.get('/movies').json() export const updateMovie = (id, comment) => - ky.post(`/movies/${id}`, { json: { comment } }).json(); + ky.post(`/movies/${id}`, { json: { comment } }).json() export const worker = setupWorker( ...[ - rest.get("/movies", (req, res, ctx) => { + rest.get('/movies', (req, res, ctx) => { return res( ctx.delay(1000), ctx.json({ ts: Date.now(), movies: movies.map(({ id, title }) => ({ id, title })), - }) - ); + }), + ) }), - rest.get("/movies/:id", (req, res, ctx) => { - const { id } = req.params; + rest.get('/movies/:id', (req, res, ctx) => { + const { id } = req.params - const movie = movies.find((movie) => movie.id === id); + const movie = movies.find((movie) => movie.id === id) if (!movie) { - return res(ctx.status(404, `Movie with id ${id} not found`)); + return res(ctx.status(404, `Movie with id ${id} not found`)) } return res( @@ -43,25 +43,25 @@ export const worker = setupWorker( ctx.json({ ts: Date.now(), movie, - }) - ); + }), + ) }), - rest.post("/movies/:id", (req, res, ctx) => { - const { id } = req.params; - const { comment } = req.body; + rest.post('/movies/:id', (req, res, ctx) => { + const { id } = req.params + const { comment } = req.body movies.forEach((movie) => { if (movie.id === id) { - movie.comment = comment.toUpperCase(); + movie.comment = comment.toUpperCase() } - }); + }) return res( ctx.delay(1000), ctx.json({ message: `Successfully updated movie ${id}`, - }) - ); + }), + ) }), - ] -); + ], +) diff --git a/examples/react/offline/src/index.jsx b/examples/react/offline/src/index.jsx index 98b53092e8..026a35b323 100644 --- a/examples/react/offline/src/index.jsx +++ b/examples/react/offline/src/index.jsx @@ -1,13 +1,13 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import App from "./App"; -import { worker } from "./api"; +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App' +import { worker } from './api' -worker.start(); +worker.start() -const rootElement = document.getElementById("root"); +const rootElement = document.getElementById('root') ReactDOM.createRoot(rootElement).render( -
+
-
-); +
, +) diff --git a/examples/react/offline/src/movies.js b/examples/react/offline/src/movies.js index 67999c5ec9..12fb656539 100644 --- a/examples/react/offline/src/movies.js +++ b/examples/react/offline/src/movies.js @@ -1,32 +1,32 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import * as api from "./api"; -import * as React from "react"; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' +import * as api from './api' +import * as React from 'react' export const movieKeys = { - all: () => ["movies"], - list: () => [...movieKeys.all(), "list"], - details: () => [...movieKeys.all(), "detail"], + all: () => ['movies'], + list: () => [...movieKeys.all(), 'list'], + details: () => [...movieKeys.all(), 'detail'], detail: (id) => [...movieKeys.details(), id], -}; +} export const useMovie = (movieId) => { - const queryClient = useQueryClient(); + const queryClient = useQueryClient() const movieQuery = useQuery({ queryKey: movieKeys.detail(movieId), queryFn: () => api.fetchMovie(movieId), - }); + }) - const [comment, setComment] = React.useState(); + const [comment, setComment] = React.useState() const updateMovie = useMutation({ mutationKey: movieKeys.detail(movieId), onMutate: async () => { - await queryClient.cancelQueries({ queryKey: movieKeys.detail(movieId) }); - const previousData = queryClient.getQueryData(movieKeys.detail(movieId)); + await queryClient.cancelQueries({ queryKey: movieKeys.detail(movieId) }) + const previousData = queryClient.getQueryData(movieKeys.detail(movieId)) // remove local state so that server state is taken instead - setComment(undefined); + setComment(undefined) queryClient.setQueryData(movieKeys.detail(movieId), { ...previousData, @@ -34,22 +34,22 @@ export const useMovie = (movieId) => { ...previousData.movie, comment, }, - }); + }) - return { previousData }; + return { previousData } }, onError: (_, __, context) => { - queryClient.setQueryData(movieKeys.detail(movieId), context.previousData); + queryClient.setQueryData(movieKeys.detail(movieId), context.previousData) }, onSettled: () => { - queryClient.invalidateQueries({ queryKey: movieKeys.detail(movieId) }); + queryClient.invalidateQueries({ queryKey: movieKeys.detail(movieId) }) }, - }); + }) return { comment: comment ?? movieQuery.data?.movie.comment, setComment, updateMovie, movieQuery, - }; -}; + } +} diff --git a/examples/react/optimistic-updates-typescript/pages/api/data.js b/examples/react/optimistic-updates-typescript/src/pages/api/data.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/optimistic-updates-typescript/pages/api/data.js rename to examples/react/optimistic-updates-typescript/src/pages/api/data.js diff --git a/examples/react/optimistic-updates-typescript/pages/index.tsx b/examples/react/optimistic-updates-typescript/src/pages/index.tsx old mode 100755 new mode 100644 similarity index 100% rename from examples/react/optimistic-updates-typescript/pages/index.tsx rename to examples/react/optimistic-updates-typescript/src/pages/index.tsx diff --git a/examples/react/optimistic-updates-typescript/tsconfig.json b/examples/react/optimistic-updates-typescript/tsconfig.json index aebbceec22..d04e1b9de1 100644 --- a/examples/react/optimistic-updates-typescript/tsconfig.json +++ b/examples/react/optimistic-updates-typescript/tsconfig.json @@ -1,5 +1,4 @@ { - "include": ["./pages/**/*"], "compilerOptions": { "strict": true, "esModuleInterop": true, @@ -16,5 +15,6 @@ "isolatedModules": true, "incremental": true }, + "include": ["src"], "exclude": ["node_modules"] } diff --git a/examples/react/pagination/pages/api/projects.js b/examples/react/pagination/src/pages/api/projects.js old mode 100755 new mode 100644 similarity index 100% rename from examples/react/pagination/pages/api/projects.js rename to examples/react/pagination/src/pages/api/projects.js diff --git a/examples/react/pagination/pages/index.js b/examples/react/pagination/src/pages/index.js similarity index 100% rename from examples/react/pagination/pages/index.js rename to examples/react/pagination/src/pages/index.js diff --git a/examples/react/playground/.prettierrc b/examples/react/playground/.prettierrc deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/examples/react/playground/.prettierrc +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/examples/react/playground/package.json b/examples/react/playground/package.json index 628a95dbb5..f7aeb72533 100644 --- a/examples/react/playground/package.json +++ b/examples/react/playground/package.json @@ -8,10 +8,10 @@ "preview": "vite preview" }, "dependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0", "@tanstack/react-query": "^5.0.0-alpha.38", - "@tanstack/react-query-devtools": "^5.0.0-alpha.38" + "@tanstack/react-query-devtools": "^5.0.0-alpha.38", + "react": "^18.2.0", + "react-dom": "^18.2.0" }, "devDependencies": { "@vitejs/plugin-react": "^4.0.0", diff --git a/examples/react/playground/src/index.jsx b/examples/react/playground/src/index.jsx index 1bb801f72d..be22c2140f 100644 --- a/examples/react/playground/src/index.jsx +++ b/examples/react/playground/src/index.jsx @@ -1,5 +1,5 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; +import React from 'react' +import ReactDOM from 'react-dom/client' import { QueryClient, @@ -7,42 +7,40 @@ import { useQuery, useQueryClient, useMutation, -} from "@tanstack/react-query"; +} from '@tanstack/react-query' -import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' -import "./styles.css"; +import './styles.css' -let id = 0; +let id = 0 let list = [ - "apple", - "banana", - "pineapple", - "grapefruit", - "dragonfruit", - "grapes", -].map((d) => ({ id: id++, name: d, notes: "These are some notes" })); + 'apple', + 'banana', + 'pineapple', + 'grapefruit', + 'dragonfruit', + 'grapes', +].map((d) => ({ id: id++, name: d, notes: 'These are some notes' })) -let errorRate = 0.05; -let queryTimeMin = 1000; -let queryTimeMax = 2000; +let errorRate = 0.05 +let queryTimeMin = 1000 +let queryTimeMax = 2000 -const queryClient = new QueryClient(); +const queryClient = new QueryClient() function Root() { - const [staleTime, setStaleTime] = React.useState(1000); - const [gcTime, setgcTime] = React.useState(3000); - const [localErrorRate, setErrorRate] = React.useState(errorRate); - const [localFetchTimeMin, setLocalFetchTimeMin] = - React.useState(queryTimeMin); - const [localFetchTimeMax, setLocalFetchTimeMax] = - React.useState(queryTimeMax); + const [staleTime, setStaleTime] = React.useState(1000) + const [gcTime, setgcTime] = React.useState(3000) + const [localErrorRate, setErrorRate] = React.useState(errorRate) + const [localFetchTimeMin, setLocalFetchTimeMin] = React.useState(queryTimeMin) + const [localFetchTimeMax, setLocalFetchTimeMax] = React.useState(queryTimeMax) React.useEffect(() => { - errorRate = localErrorRate; - queryTimeMin = localFetchTimeMin; - queryTimeMax = localFetchTimeMax; - }, [localErrorRate, localFetchTimeMax, localFetchTimeMin]); + errorRate = localErrorRate + queryTimeMin = localFetchTimeMin + queryTimeMax = localFetchTimeMax + }, [localErrorRate, localFetchTimeMax, localFetchTimeMin]) React.useEffect(() => { queryClient.setDefaultOptions({ @@ -50,8 +48,8 @@ function Root() { staleTime, gcTime, }, - }); - }, [gcTime, staleTime]); + }) + }, [gcTime, staleTime]) return ( @@ -60,30 +58,30 @@ function Root() { to show how query stale-ness and query caching work on a granular level

- Stale Time:{" "} + Stale Time:{' '} setStaleTime(parseFloat(e.target.value, 10))} - style={{ width: "100px" }} + style={{ width: '100px' }} />
- Garbage collection Time:{" "} + Garbage collection Time:{' '} setgcTime(parseFloat(e.target.value, 10))} - style={{ width: "100px" }} + style={{ width: '100px' }} />

- Error Rate:{" "} + Error Rate:{' '} setErrorRate(parseFloat(e.target.value, 10))} - style={{ width: "100px" }} + style={{ width: '100px' }} />
- Fetch Time Min:{" "} + Fetch Time Min:{' '} setLocalFetchTimeMin(parseFloat(e.target.value, 10))} - style={{ width: "60px" }} - />{" "} + style={{ width: '60px' }} + />{' '}
- Fetch Time Max:{" "} + Fetch Time Max:{' '} setLocalFetchTimeMax(parseFloat(e.target.value, 10))} - style={{ width: "60px" }} + style={{ width: '60px' }} />

@@ -121,13 +119,13 @@ function Root() {
- ); + ) } function App() { - const queryClient = useQueryClient(); - const [editingIndex, setEditingIndex] = React.useState(null); - const [views, setViews] = React.useState(["", "fruit", "grape"]); + const queryClient = useQueryClient() + const [editingIndex, setEditingIndex] = React.useState(null) + const [views, setViews] = React.useState(['', 'fruit', 'grape']) // const [views, setViews] = React.useState([""]); return ( @@ -145,7 +143,7 @@ function App() { initialFilter={view} setEditingIndex={setEditingIndex} onRemove={() => { - setViews((old) => [...old, ""]); + setViews((old) => [...old, '']) }} />
@@ -153,7 +151,7 @@ function App() { ))} @@ -223,44 +221,44 @@ function Todos({ initialFilter = "", setEditingIndex }) { )} - ); + ) } function EditTodo({ editingIndex, setEditingIndex }) { - const queryClient = useQueryClient(); + const queryClient = useQueryClient() // Don't attempt to query until editingIndex is truthy const { status, data, isFetching, error, failureCount, refetch } = useQuery({ - queryKey: ["todo", { id: editingIndex }], + queryKey: ['todo', { id: editingIndex }], queryFn: () => fetchTodoById({ id: editingIndex }), enabled: editingIndex !== null, - }); + }) - const [todo, setTodo] = React.useState(data || {}); + const [todo, setTodo] = React.useState(data || {}) React.useEffect(() => { if (editingIndex !== null && data) { - setTodo(data); + setTodo(data) } else { - setTodo({}); + setTodo({}) } - }, [data, editingIndex]); + }, [data, editingIndex]) const saveMutation = useMutation({ mutationFn: patchTodo, onSuccess: (data) => { // Update `todos` and the individual todo queries when this mutation succeeds - queryClient.invalidateQueries({ queryKey: ["todos"] }); - queryClient.setQueryData(["todo", { id: editingIndex }], data); + queryClient.invalidateQueries({ queryKey: ['todos'] }) + queryClient.setQueryData(['todo', { id: editingIndex }], data) }, - }); + }) const onSave = () => { - saveMutation.mutate(todo); - }; + saveMutation.mutate(todo) + } const disableEditSave = - status === "pending" || saveMutation.status === "pending"; + status === 'pending' || saveMutation.status === 'pending' return (
@@ -273,7 +271,7 @@ function EditTodo({ editingIndex, setEditingIndex }) { ) : null}
- {status === "pending" ? ( + {status === 'pending' ? ( Loading... (Attempt: {failureCount + 1}) ) : error ? ( @@ -282,7 +280,7 @@ function EditTodo({ editingIndex, setEditingIndex }) { ) : ( <>