5.0 KiB
Executable File
5.0 KiB
Executable File
react-query
适用于 React Hooks 的请求库 远程数据的状态管理(也包括数据获取)
传统状态管理的缺点:
- 远程数据无法控制
- 需要写很多重复代码
- 共享数据可能被修改
- 数据可能过时
react-query的优点:
- 缓存控制
- 可以合并请求
- 在后台更新过时数据
- 知道数据什么时候过时
- 分页和延迟加载等性能优化
- 数据更新触发视图更新
- 更好的内存回收
- 存储更结构化并共享
文档
- 官方文档: https://tanstack.com/query/latest/docs/react/overview
- 中文翻译: https://cangsdarm.github.io/react-query-web-i18n/react/
- 中文教程: https://juejin.cn/post/6937833844837974053 https://segmentfault.com/a/1190000041939135
安装
pnpm add @tanstack/react-query
兼容性:
Chrome >= 73
Firefox >= 78
Edge >= 79
Safari >= 12.0
iOS >= 12.0
opera >= 53
使用
三个重要概念: 查询, 修改, 主动查询失效
查询
- 实例化 queryClient
- 用 QueryClientProvider 包裹 app
// main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import {
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query'
const queryClient = new QueryClient()
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
)
- 用 useQuery 获取 异步数据
/**
* useQuery
* - queryKey: 查询键, 是个数组, 通过不同的查询键来标识不同接口返回的不同数据, 简单理解成localstorage里的key
* - key内的元素可以是嵌套数组、对象、字符串、数字 ['zen', { form: 'confucius' }]
* - 从通用到特殊, 为了避免重复, 第一个可以是个字符串
* - 当key发生变化时, 会自动发起新的请求, 并缓存在新的key中
* - queryFn: 查询函数, 不只axios, fetch, 所有Promise都可以
* - 默认传参 {meta, pageParam, queryKey, signal}
* - 返回:
* - 状态只会是三种中的一种
* - isLoading: 加载状态
* - isError: 查询遇到一个错误
* - isSuccess: 查询成功,并且数据可用
* - data: 成功时的数据
* - error: 失败时的错误信息
*/
import axios from 'axios'
import { useQuery} from '@tanstack/react-query'
type Props = {}
const StusList = (props: Props) => {
const getStudentsList = async (key:unknown)=>{
console.log('key:', key)
try {
const res = await axios.get('${window.apiUrl}/students')
return res.data
} catch (error) {
if(error instanceof Error){
return error.message
}
}
}
const { isLoading, isError, data, error } = useQuery(['studentsList'], getStudentsList)
return (
<>
{isLoading && <span>数据正在加载中...</span>}
{data && <span>{JSON.stringify(data)}</span>}
{isError && error instanceof Error && <span>{error.message}</span>}
{/* error 默认类型为unknown, 运行时进行检查 */}
</>
)
}
export default StusList
并行查询
import axios from 'axios'
import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
const ParallelRequest = () => {
const user1Query = useQuery(['stuInfo', 1], () => {
return axios.get(`${window.apiUrl}/students/1`).then(res => res.data)
})
const user2Query = useQuery(['stuInfo', 2], () => {
return axios.get(`${window.apiUrl}/students/2`).then(res => res.data)
})
const query = useQuery(['stuInfo', '1&2'], () => {
return Promise.all([
axios.get(`${window.apiUrl}/students/1`).then(res => res.data),
axios.get(`${window.apiUrl}/students/2`).then(res => res.data),
])
})
return (
<div>
先完成先展示:
{user1Query.isLoading && <p>用户1正在加载中...</p>}
{user1Query.isError && <p>用户1数据获取错误!</p>}
{user1Query.data && <p>用户1数据:{JSON.stringify(user1Query.data)}</p>}
{user2Query.isLoading && <p>用户2正在加载中...</p>}
{user2Query.isError && <p>用户2数据获取错误!</p>}
{user2Query.data && <p>用户2数据:{JSON.stringify(user2Query.data)}</p>}
<br />
全部完成再展示:
{query.isLoading && <p>正在加载中...</p>}
{query.isError && <p>请求错误!</p>}
{query.data && <p>{JSON.stringify(query.data)}</p>}
</div>
)
}
export default ParallelRequest
第一部分 用户1, 用户2的数据, 谁先完成获取就展示谁
第二部分, 用户1 用户2全部获取完成后, 再进行展示, 在查询函数中使用了Promise.all
动态并行查询
查询数量在每次渲染时会发生变化, 不能使用手动查询, 使用
useQueries
举例: 第一次查询react, vue
两个项目的仓库, 第二次查询 selvte, ## Angular
一个项目的仓库
修改
使查询失效