React Query(管理和缓存数据)
github https://github.com/tanstack/query
npm i @tanstack/react-query
//main.tsx引入 ...
import { QueryClient,QueryClientProvider } from '@tanstack/react-query' const queryClient = new QueryClient({ defaultOptions:{//默认可以不需要 全局设置 queries:{ retry:3,//接口调用失败,再次调用的次数 cacheTime:300_000,//5m 接口调用多久清除缓存 staleTime:10*1000,//10s 接口刷新时间 refetchOnWindowFocus:false,//默认 true 打开其它标签,再次聚焦此个标签是否触发 refetchOnReconnect:false,//默认true 断网重新连接时是否触发 refetchOnMount:false //默认 true 组件挂载时是否触发 } } }) ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode>
<QueryClientProvider clinet={queryClient}> <App /> </QueryClientProvider>
</React.StrictMode>, )
例子
interface ListData {
} const List = ()=>{
const getList = ()=>{ axios.get('url').then(res=>res.data)
}
//使用useQuery hook const { data,error,isLoading } = useQuery<ListData[],Error>({ queryKey:['todos'], queryFn:getList, //也可以在这里吗配置 retry:3,//接口调用失败,再次调用的次数 cacheTime:300_000,//5m 接口调用多久清除缓存 staleTime:10*1000,//10s 接口刷新时间 refetchOnWindowFocus:false,//默认 true 打开其它标签,再次聚焦此个标签是否触发 refetchOnReconnect:false,//默认true 断网重新连接时是否触发 refetchOnMount:false //默认 true 组件挂载时是否触发 })
if(isLoading) return <p>loading</p>
if(error) return <p>{error.message}</p>
return( <ul> { data?.map(item=>( <li key={item.id}>{item.title}</li> )) } </ul> )
}
export default List
使用react-query-devtools
npm i @tanstack/react-query-devtools
动态传值
const usePosts = (userId:string|undefined) => useQuery<Posts[],error>({ queryKey:userId?["user",userId,"posts"]:["posts"], queryFn:()=> axios.get('url',{ params:{userId} }).then(res=>res.data), staleTime:1601000,//1min 接口刷新时间 })
export default usePosts
分页
const PostList = () =>{
}
interface PostQuery{ page:number, pageSize:number|10 }
const usePosts = (query:PostQuery) => useQuery<Posts[],error>({ queryKey:["posts",query], queryFn:()=> axios.get('url',{ params:{ _page:query.page, _limit:query.pageSize } }).then(res=>res.data), staleTime:1601000,//1min 接口刷新时间 keepPreviousData:true//相当于关闭loading,请求没结束之前界面数据始终是上次数据 })
export default usePosts
无限请求/加载更多/瀑布流
interface PostQuery{ pageSize:number }
const usePosts = (query:PostQuery) => useInfiniteQuery<Posts[],error>({ queryKey:["posts",query], queryFn:({pageNum=1})=> axios.get('url',{ params:{ _page:pageNum, _limit:query.pageSize } }).then(res=>res.data), staleTime:1601000,//1min 接口刷新时间 keepPreviousData:true,//相当于关闭loading,请求没结束之前界面数据始终是上次数据 getNextPageParam:(lastPage,allPages)=>{ //1->2 return lastPage.length>0?allPages.length + 1:undefined } })
export default usePosts
... import usePosts from './hooks/usePosts' const PostsList = ()=>{ const {data,error,isLoading,fetchNextPage,isFetchingNextPage} = usePosts<Posts[],error>
... return( <> <ul> {data.pages.map(page,index=> <React.Fragment key={index}> {page.map(item=>( <li :key={item.id}>{item.name}</li> ))}
</React.Fragment>
)} </ul> <button disabled={isFetchingNextPage} onClick={()=>fetchNextPage()}> {isFetchingNextPage?'加载中...':'加载更多'} </button>
</> )
export default PostsList