如何在同一页面中使用useSWR发起多个请求
同页面发起多个useSWR请求的实现方式
你之前的写法不生效,是因为useSWR固定返回的属性名只有data、error、isLoading等,直接解构userData、coinError这类自定义名称是拿不到值的,需要用到JS对象解构的重命名语法。
最常用的最佳实践就是直接声明多个useSWR钩子,每个钩子对应一个请求,解构时对返回值做重命名区分即可,示例如下:
// 通用fetcher可以复用,不需要重复声明 const fetcher = (...args) => fetch(...args).then((res) => res.json()); // 第一个请求:获取币种数据,重命名返回值避免冲突 const { data: coinData, error: coinError, isLoading: coinLoading } = useSWR( `https://api.coingecko.com/api/v3/coins/${coinURL}`, fetcher ); // 第二个请求:获取用户数据,独立的请求和缓存逻辑 const { data: userData, error: userError, isLoading: userLoading } = useSWR( "/api/your/user/endpoint", // 替换为你自己的用户接口地址 fetcher ); // 可分别处理每个请求的错误和加载状态 if (coinError) return <div>币种数据加载失败</div>; if (userError) return <div>用户数据加载失败</div>; if (coinLoading || userLoading) return <div>加载中...</div>; // 所有请求完成后渲染内容 return ( <div> <div>币种名称:{coinData.name}</div> <div>用户名:{userData.nickname}</div> </div> );
如果需要一次性批量发起多个强关联的并行请求,也可以用数组作为key的写法:
const { data: [coinData, userData], error } = useSWR( [ `https://api.coingecko.com/api/v3/coins/${coinURL}`, "/api/your/user/endpoint" ], (url1, url2) => Promise.all([ fetch(url1).then(res => res.json()), fetch(url2).then(res => res.json()) ]) )
这种方式的错误和加载状态是统一的,适合请求关联度高的场景,灵活度低于单独声明多个钩子。
注意事项
- 每个useSWR的第一个参数为缓存key,必须保证唯一,如果两个钩子使用完全相同的key,SWR会直接复用已有缓存,不会发起重复请求。
- 多个useSWR钩子默认是并行发起请求的,不需要额外做并行处理,性能和单独发axios请求一致。
- 如果多个请求存在依赖关系(比如第二个请求需要第一个请求的返回值作为参数),可以给第二个请求的key传入
null来暂停请求,等依赖参数准备好后再传入有效值即可。
内容的提问来源于stack exchange,提问作者Eric Pezzulo
相关产品推荐
相关产品推荐

