将Redux Toolkit Query转为SWR并实现TS接口数组类型转换遇阻求助
问题:RTK Query转SWR后无法正常工作且TypeScript类型不匹配
原RTK Query实现代码
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; interface Blog { id: string; name: string; blog:string; image: { url: string; }; } export const myApi = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost/blogs', prepareHeaders(headers) { headers.set('x-api-key', 'mykeyfdafdaffdafdafdas'); return headers; }, }), endpoints(builder) { return { fetchBlogs: builder.query({ query(limit = 10) { return `/blogs?limit=${limit}`; }, }), }; }, }); export const { useFetchBlogsQuery } = myApi;
有问题的SWR实现代码
const fetcher = (url:string) => fetch(url,{ mode: 'cors', headers:{ 'x-api-key': 'mykeyfdafdaffdafdafdas', 'User-Agent': 'My-App', 'Accept': '*/*' } }).then((res) =>{ console.log(res.body); res.json()}).catch(error=> console.log('error while fetching:', error)); const { data =[] } = useSwr<Blog>(`http://localhost/blog`, fetcher);
解决方法
1. 修正请求URL
原RTK Query的完整请求URL是http://localhost/blogs/blogs?limit=10(baseUrl + 接口路径),你当前SWR里的URLhttp://localhost/blog完全不匹配,需要改成一致的路径:
const limit = 10; const { data = [] } = useSwr<Blog[]>(`http://localhost/blogs/blogs?limit=${limit}`, fetcher);
2. 修正TypeScript泛型类型
接口返回的是Blog数组,所以useSwr的泛型必须是Blog[]而非Blog,否则会出现类型不匹配:
const { data = [] } = useSwr<Blog[]>(/* 正确URL */, fetcher);
3. 修复fetcher函数逻辑
then回调里没有return res.json(),导致fetcher返回Promise<undefined>,SWR拿不到数据res.body是可读流,直接打印看不到有效内容,应该打印解析后的JSON数据- 不要在fetcher里吞掉错误,要抛出错误让SWR处理错误状态
修正后的fetcher:
const fetcher = async (url: string) => { const res = await fetch(url, { mode: 'cors', headers: { 'x-api-key': 'mykeyfdafdaffdafdafdas', 'User-Agent': 'My-App', 'Accept': '*/*' } }); // 非2xx状态码抛出错误 if (!res.ok) { throw new Error(`请求失败: ${res.status}`); } const data = await res.json(); console.log('获取到的数据:', data); return data; };
4. 完整修正后的SWR代码
interface Blog { id: string; name: string; blog: string; image: { url: string; }; } const fetcher = async (url: string) => { const res = await fetch(url, { mode: 'cors', headers: { 'x-api-key': 'mykeyfdafdaffdafdafdas', 'User-Agent': 'My-App', 'Accept': '*/*' } }); if (!res.ok) { throw new Error(`请求失败: ${res.status}`); } return res.json() as Promise<Blog[]>; }; const limit = 10; const { data = [], error, isLoading } = useSwr<Blog[]>( `http://localhost/blogs/blogs?limit=${limit}`, fetcher );
内容的提问来源于stack exchange,提问作者Joon w K
相关产品推荐
相关产品推荐

