useSWR成功请求API但返回data为undefined的问题解决
问题:useSWR获取数据后data始终为undefined,网络请求却成功
我正在使用useSWR钩子从API获取并展示数据,代码如下:
const backendURL = process.env.NEXT_PUBLIC_BACKEND_URL; const { data: session, status } = useSession(); let userToken = null; useEffect(() => { if (status == "authenticated") { console.log(status); userToken = session.user.accessToken; console.log(session.user.accessToken); } }, [session, status]); const fetcher = (url) => { axios .get(url, { headers: { Authorization: `Bearer ${session.user.accessToken}`, "Content-Type": "application/json", }, }) .then((res) => { return res; }) .catch((err) => console.log(err)); }; const { data, error, isLoading, isValidating } = useSWR( `${backendURL}/content/get_all/content_type`, fetcher, { refreshInterval: 1000 } );
当我在.then()函数中打印响应(如.then((res) => console.log(res)))时,能看到输出结果,且网络请求面板显示数据已成功获取,但执行console.log(data)时始终返回undefined。请问该如何解决此问题?
我的依赖版本如下:
"dependencies": { "@svgr/webpack": "^6.5.1", "antd": "^4.23.4", "axios": "^1.2.2", "cookies-next": "^2.1.1", "less": "^4.1.3", "next": "^12.2.5", "next-auth": "^4.18.8", "react": "^18.2.0", "react-calendar": "^4.0.0", "react-cookie": "^4.1.1", "react-dom": "^18.2.0", "swr": "^2.0.0" }, "devDependencies": { "@types/node": "18.7.23", "@types/react": "18.0.21", "@types/react-dom": "18.0.6", "autoprefixer": "^10.4.12", "eslint": "8.24.0", "eslint-config-next": "^13.1.1", "postcss": "^8.4.17", "tailwindcss": "^3.2.4" }
解决方案
1. 让fetcher返回Promise
useSWR依赖fetcher返回的Promise来解析数据,当前你的fetcher函数没有返回axios请求的Promise,导致useSWR无法拿到结果。
修复后的fetcher:
const fetcher = (url) => { return axios .get(url, { headers: { Authorization: `Bearer ${session.user.accessToken}`, "Content-Type": "application/json", }, }) .then((res) => { // 建议返回res.data(API返回的实际数据),而非整个响应对象 return res.data; }) .catch((err) => { console.log(err); // 抛出错误,让useSWR捕获并设置error状态 throw err; }); };
2. 条件化SWR请求触发时机
组件挂载时session可能还未完成认证,此时发起请求会导致token无效,也可能让useSWR拿到异常结果。通过设置SWR的key为null,可以在未认证时暂停请求:
const { data, error, isLoading, isValidating } = useSWR( status === "authenticated" ? `${backendURL}/content/get_all/content_type` : null, fetcher, { refreshInterval: 1000 } );
3. 移除冗余的userToken变量
你定义的userToken变量并未在代码中使用,直接删除即可,避免代码冗余。
4. 完善错误处理
在catch中抛出错误,这样useSWR的error状态会被正确触发,方便在组件中处理错误场景(比如展示错误提示)。
内容的提问来源于stack exchange,提问作者Ekim Cem Ülger
相关产品推荐
相关产品推荐

