snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
27
examples/react/prefetching/.gitignore
vendored
Normal file
27
examples/react/prefetching/.gitignore
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
6
examples/react/prefetching/README.md
Normal file
6
examples/react/prefetching/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Example
|
||||
|
||||
To run this example:
|
||||
|
||||
- `npm install`
|
||||
- `npm run dev`
|
||||
13
examples/react/prefetching/next.config.js
Normal file
13
examples/react/prefetching/next.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
eslint: {
|
||||
ignoreDuringBuilds: true,
|
||||
},
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
22
examples/react/prefetching/package.json
Normal file
22
examples/react/prefetching/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@tanstack/query-example-react-prefetching",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev --webpack",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "^5.102.8",
|
||||
"@tanstack/react-query-devtools": "^5.102.8",
|
||||
"next": "^16.0.7",
|
||||
"react": "^19.2.1",
|
||||
"react-dom": "^19.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"typescript": "5.8.3"
|
||||
}
|
||||
}
|
||||
48
examples/react/prefetching/src/pages/[user]/[repo].tsx
Normal file
48
examples/react/prefetching/src/pages/[user]/[repo].tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { usePathname } from 'next/navigation'
|
||||
|
||||
async function fetchProject(id: string): Promise<{
|
||||
forks_count: number
|
||||
stargazers_count: number
|
||||
watchers_count: number
|
||||
}> {
|
||||
console.info('Fetching project:', id)
|
||||
|
||||
const response = await fetch(`https://api.github.com/repos/${id}`)
|
||||
await new Promise((r) => setTimeout(r, 1000))
|
||||
return await response.json()
|
||||
}
|
||||
|
||||
export default function Repo() {
|
||||
const id = usePathname()
|
||||
|
||||
const { status, data, error, isFetching } = useQuery({
|
||||
queryKey: ['team', id],
|
||||
queryFn: () => fetchProject(id),
|
||||
})
|
||||
|
||||
return (
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<h1>{id}</h1>
|
||||
{status === 'pending' ? (
|
||||
'Loading...'
|
||||
) : status === 'error' ? (
|
||||
<span>Error: {error.message}</span>
|
||||
) : (
|
||||
<>
|
||||
<div>
|
||||
<p>forks: {data.forks_count}</p>
|
||||
<p>stars: {data.stargazers_count}</p>
|
||||
<p>watchers: {data.watchers_count}</p>
|
||||
</div>
|
||||
<div>{isFetching ? 'Background Updating...' : ' '}</div>
|
||||
</>
|
||||
)}
|
||||
<br />
|
||||
<br />
|
||||
<Link href="/">Back</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
13
examples/react/prefetching/src/pages/_app.tsx
Normal file
13
examples/react/prefetching/src/pages/_app.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
const [queryClient] = React.useState(() => new QueryClient())
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Component {...pageProps} />
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
97
examples/react/prefetching/src/pages/index.tsx
Normal file
97
examples/react/prefetching/src/pages/index.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import React from 'react'
|
||||
import { noop, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
|
||||
const getCharacters = async (): Promise<{
|
||||
results: Array<{ id: number; name: string }>
|
||||
}> => {
|
||||
await new Promise((r) => setTimeout(r, 500))
|
||||
const response = await fetch('https://rickandmortyapi.com/api/character/')
|
||||
return await response.json()
|
||||
}
|
||||
|
||||
const getCharacter = async (selectedChar: number) => {
|
||||
await new Promise((r) => setTimeout(r, 500))
|
||||
const response = await fetch(
|
||||
`https://rickandmortyapi.com/api/character/${selectedChar}`,
|
||||
)
|
||||
return await response.json()
|
||||
}
|
||||
|
||||
export default function Example() {
|
||||
const queryClient = useQueryClient()
|
||||
const rerender = React.useState(0)[1]
|
||||
const [selectedChar, setSelectedChar] = React.useState(1)
|
||||
|
||||
const charactersQuery = useQuery({
|
||||
queryKey: ['characters'],
|
||||
queryFn: getCharacters,
|
||||
})
|
||||
|
||||
const characterQuery = useQuery({
|
||||
queryKey: ['character', selectedChar],
|
||||
queryFn: () => getCharacter(selectedChar),
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<p>
|
||||
Hovering over a character will prefetch it, and when it's been
|
||||
prefetched it will turn <strong>bold</strong>. Clicking on a prefetched
|
||||
character will show their stats below immediately.
|
||||
</p>
|
||||
<h2>Characters</h2>
|
||||
{charactersQuery.isPending ? (
|
||||
'Loading...'
|
||||
) : (
|
||||
<>
|
||||
<ul>
|
||||
{charactersQuery.data?.results.map((char) => (
|
||||
<li
|
||||
key={char.id}
|
||||
onClick={() => {
|
||||
setSelectedChar(char.id)
|
||||
}}
|
||||
onMouseEnter={async () => {
|
||||
await queryClient
|
||||
.query({
|
||||
queryKey: ['character', char.id],
|
||||
queryFn: () => getCharacter(char.id),
|
||||
staleTime: 10 * 1000, // only prefetch if older than 10 seconds
|
||||
})
|
||||
.catch(noop)
|
||||
|
||||
setTimeout(() => {
|
||||
rerender({})
|
||||
}, 1)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={
|
||||
queryClient.getQueryData(['character', char.id])
|
||||
? {
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
{char.id} - {char.name}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<h3>Selected Character</h3>
|
||||
{characterQuery.isPending ? (
|
||||
'Loading...'
|
||||
) : (
|
||||
<>
|
||||
<pre>{JSON.stringify(characterQuery.data, null, 2)}</pre>
|
||||
</>
|
||||
)}
|
||||
<ReactQueryDevtools initialIsOpen />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
20
examples/react/prefetching/tsconfig.json
Normal file
20
examples/react/prefetching/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react-jsx",
|
||||
"incremental": true,
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user