11import { createRoot } from 'react-dom/client'
2+ import { createContext , useContext , useState } from 'react'
3+ import { createPortal } from 'react-dom'
4+ import {
5+ QueryClient ,
6+ QueryClientProvider ,
7+ useQuery ,
8+ useQueryClient ,
9+ } from '@tanstack/react-query'
210import Devtools from './setup'
311import { queryPlugin } from './plugin'
412import { Button } from './button'
513import { Feature } from './feature'
614
15+ const queryClient = new QueryClient ( {
16+ defaultOptions : {
17+ queries : {
18+ gcTime : 1000 * 60 * 60 * 24 , // 24 hours
19+ } ,
20+ } ,
21+ } )
22+
23+ type Post = {
24+ id : number
25+ title : string
26+ body : string
27+ }
28+
29+ function Posts ( {
30+ setPostId,
31+ } : {
32+ setPostId : React . Dispatch < React . SetStateAction < number > >
33+ } ) {
34+ const queryClient = useQueryClient ( )
35+ const { status, data, error, isFetching } = usePosts ( )
36+
37+ return (
38+ < div >
39+ < h1 > Posts</ h1 >
40+ < div >
41+ { status === 'pending' ? (
42+ 'Loading...'
43+ ) : status === 'error' ? (
44+ < span > Error: { error . message } </ span >
45+ ) : (
46+ < >
47+ < div >
48+ { data . map ( ( post ) => (
49+ < p key = { post . id } >
50+ < a
51+ onClick = { ( ) => setPostId ( post . id ) }
52+ href = "#"
53+ style = {
54+ // We can access the query data here to show bold links for
55+ // ones that are cached
56+ queryClient . getQueryData ( [ 'post' , post . id ] )
57+ ? {
58+ fontWeight : 'bold' ,
59+ color : 'green' ,
60+ }
61+ : { }
62+ }
63+ >
64+ { post . title }
65+ </ a >
66+ </ p >
67+ ) ) }
68+ </ div >
69+ < div > { isFetching ? 'Background Updating...' : ' ' } </ div >
70+ </ >
71+ ) }
72+ </ div >
73+ </ div >
74+ )
75+ }
76+
77+ const getPostById = async ( id : number ) : Promise < Post > => {
78+ const response = await fetch (
79+ `https://jsonplaceholder.typicode.com/posts/${ id } ` ,
80+ )
81+ return await response . json ( )
82+ }
83+
84+ function usePost ( postId : number ) {
85+ return useQuery ( {
86+ queryKey : [ 'post' , postId ] ,
87+ queryFn : ( ) => getPostById ( postId ) ,
88+ enabled : ! ! postId ,
89+ } )
90+ }
91+
92+ function Post ( {
93+ postId,
94+ setPostId,
95+ } : {
96+ postId : number
97+ setPostId : React . Dispatch < React . SetStateAction < number > >
98+ } ) {
99+ const { status, data, error, isFetching } = usePost ( postId )
100+
101+ return (
102+ < div >
103+ < div >
104+ < a onClick = { ( ) => setPostId ( - 1 ) } href = "#" >
105+ Back
106+ </ a >
107+ </ div >
108+ { ! postId || status === 'pending' ? (
109+ 'Loading...'
110+ ) : status === 'error' ? (
111+ < span > Error: { error . message } </ span >
112+ ) : (
113+ < >
114+ < h1 > { data . title } </ h1 >
115+ < div >
116+ < p > { data . body } </ p >
117+ </ div >
118+ < div > { isFetching ? 'Background Updating...' : ' ' } </ div >
119+ </ >
120+ ) }
121+ </ div >
122+ )
123+ }
124+ function usePosts ( ) {
125+ return useQuery ( {
126+ queryKey : [ 'posts' ] ,
127+ queryFn : async ( ) : Promise < Array < Post > > => {
128+ const response = await fetch ( 'https://jsonplaceholder.typicode.com/posts' )
129+ return await response . json ( )
130+ } ,
131+ } )
132+ }
133+
134+ const Context = createContext < {
135+ count : number
136+ setCount : ( count : number ) => void
137+ } > ( { count : 0 , setCount : ( ) => { } } )
138+
7139setTimeout ( ( ) => {
8140 queryPlugin . emit ( 'test' , {
9141 title : 'Test Event' ,
@@ -16,13 +148,56 @@ queryPlugin.on('test', (event) => {
16148 console . log ( 'Received test event:' , event )
17149} )
18150
151+ function Mounted ( ) {
152+ const c = useContext ( Context )
153+ console . log ( c )
154+ return (
155+ < p
156+ onClick = { ( ) => {
157+ c . setCount ( c . count + 1 )
158+ } }
159+ >
160+ { c . count }
161+ < hr />
162+ </ p >
163+ )
164+ }
165+
19166function App ( ) {
167+ const [ state , setState ] = useState ( 1 )
168+ const [ win , setWin ] = useState < Window | null > ( null )
169+ const [ postId , setPostId ] = useState ( - 1 )
20170 return (
21171 < div >
22- < h1 > TanStack Devtools React Basic Example</ h1 >
23- < Button > Click me</ Button >
24- < Feature />
25- < Devtools />
172+ < Context . Provider value = { { count : state , setCount : setState } } >
173+ < QueryClientProvider client = { queryClient } >
174+ < p >
175+ As you visit the posts below, you will notice them in a loading
176+ state the first time you load them. However, after you return to
177+ this list and click on any posts you have already visited again, you
178+ will see them load instantly and background refresh right before
179+ your eyes!{ ' ' }
180+ < strong >
181+ (You may need to throttle your network speed to simulate longer
182+ loading sequences)
183+ </ strong >
184+ </ p >
185+ { postId > - 1 ? (
186+ < Post postId = { postId } setPostId = { setPostId } />
187+ ) : (
188+ < Posts setPostId = { setPostId } />
189+ ) }
190+ < Devtools />
191+ </ QueryClientProvider >
192+ < h1 > TanStack Devtools React Basic Example</ h1 >
193+ current count: { state }
194+ < Button onClick = { ( ) => setState ( state + 1 ) } > Click me</ Button >
195+ < Button onClick = { ( ) => setWin ( window . open ( '' , '' , 'popup' ) ) } >
196+ Click me to open new window
197+ </ Button >
198+ { win && createPortal ( < Mounted /> , win . document . body ) }
199+ < Feature />
200+ </ Context . Provider >
26201 </ div >
27202 )
28203}
0 commit comments