11import * as React from 'react'
2- import axios from 'axios'
2+ import axios , { AxiosError } from 'axios'
33
44import {
55 useQuery ,
66 useQueryClient ,
77 useMutation ,
88 QueryClient ,
99 QueryClientProvider ,
10+ UseQueryOptions ,
1011} from 'react-query'
1112import { ReactQueryDevtools } from 'react-query-devtools'
1213
@@ -16,17 +17,17 @@ export default function App() {
1617 return (
1718 < QueryClientProvider client = { client } >
1819 < Example />
20+ < TodoCounter />
21+ < ReactQueryDevtools initialIsOpen />
1922 </ QueryClientProvider >
2023 )
2124}
2225
23- type Todo = {
24- id : string
25- text : string
26- }
27-
2826type TodoData = {
29- items : readonly Todo [ ]
27+ items : readonly {
28+ id : string
29+ text : string
30+ } [ ]
3031 ts : number
3132}
3233
@@ -35,10 +36,29 @@ async function fetchTodos(): Promise<TodoData> {
3536 return res . data
3637}
3738
39+ function useTodos < TData = TodoData > (
40+ options ?: UseQueryOptions < TData , AxiosError , TodoData >
41+ ) {
42+ return useQuery < TData , AxiosError , TodoData > ( 'todos' , fetchTodos , options )
43+ }
44+
45+ function TodoCounter ( ) {
46+ const counterQuery = useTodos ( {
47+ select : data => data . items . length ,
48+ notifyOnChangeProps : [ 'data' ] ,
49+ } )
50+
51+ React . useEffect ( ( ) => {
52+ console . log ( 'rendering counter' )
53+ } )
54+
55+ return < div > TodoCounter: { counterQuery . data ?? 0 } </ div >
56+ }
57+
3858function Example ( ) {
3959 const queryClient = useQueryClient ( )
4060 const [ text , setText ] = React . useState ( '' )
41- const { isFetching, ...queryInfo } = useQuery ( 'todos' , fetchTodos )
61+ const { isFetching, ...queryInfo } = useTodos ( )
4262
4363 const addTodoMutation = useMutation (
4464 ( newTodo : string ) => axios . post ( '/api/data' , { text : newTodo } ) ,
@@ -68,7 +88,7 @@ function Example() {
6888 onError : ( err , variables , previousValue ) => {
6989 queryClient . setQueryData ( 'todos' , previousValue )
7090 } ,
71- // // After success or failure, refetch the todos query
91+ // After success or failure, refetch the todos query
7292 onSettled : ( ) => {
7393 queryClient . invalidateQueries ( 'todos' )
7494 } ,
@@ -102,6 +122,7 @@ function Example() {
102122 { queryInfo . isSuccess && (
103123 < >
104124 < div >
125+ { /* The type of queryInfo.data will be narrowed because we check for isSuccess first */ }
105126 Updated At: { new Date ( queryInfo . data . ts ) . toLocaleTimeString ( ) }
106127 </ div >
107128 < ul >
@@ -113,8 +134,7 @@ function Example() {
113134 </ >
114135 ) }
115136 { queryInfo . isLoading && 'Loading' }
116- { queryInfo . error instanceof Error && queryInfo . error . message }
117- < ReactQueryDevtools initialIsOpen />
137+ { queryInfo . error ?. message }
118138 </ div >
119139 )
120140}
0 commit comments