You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:20:47