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

useSWR加载/验证阶段返回数据规则及中间数据异常问询

useSWR返回数据规则及问题分析

核心结论

  1. useSWR不会返回fetcher回调中多步then的中间数据,它只会接收fetcher最终resolve的结果作为data的值。
  2. useSWR保证返回的data仅可能是以下几种情况:
    • undefined:初始加载阶段、请求未完成时、fetcher抛出错误(Promise被reject)时
    • 缓存的历史成功响应数据:如果之前请求成功过,会优先返回缓存数据,再进行后台重新验证
    • 配置的fallback数据:若通过fallback选项预设了初始数据,加载初期会返回对应值
    • fetcher最终resolve的结果:即你代码中第二个then返回的data.content(Foo[]类型)

你遇到的问题原因

你看到的idpData为响应JSON对象(而非预期的Foo[])的情况,并非useSWR返回了中间数据,而是你的fetcher逻辑或API响应存在异常:

  • 你的fetcher未处理HTTP错误状态码(如401、500等):当请求返回非200状态码时,fetch不会自动抛出错误,仍会执行res.json(),若此时API返回的错误JSON对象没有content字段,第二个then中data.content会是undefined;如果API在某些场景下直接返回了未经过content包裹的原始对象(而非分页结构),也会导致fetcher返回非预期值。
  • 类型定义与实际响应不匹配:你给fetcher标注了返回Promise<Foo[]>,但实际运行中API可能返回不符合结构的数据,导致类型校验失效,出现非预期的data格式。

修复方案

  1. 完善fetcher的错误处理:检查响应状态码和数据结构,主动抛出异常避免无效数据流入:
const { data: idpData } = useSWR<Foo[]>(
  buildUrl(() => `/[...]/idps`),
  async (url: string): Promise<Foo[]> => {
    const res = await fetch(url, { headers: { Authorization: `Bearer ${accessToken}` } });
    if (!res.ok) {
      throw new Error(`请求失败,状态码:${res.status}`);
    }
    const data = await res.json() as PaginationWithContentDetails;
    if (!Array.isArray(data.content)) {
      throw new Error("响应结构无效:缺少或非数组类型的'content'字段");
    }
    return data.content;
  }
);
  1. 增强渲染时的防护逻辑:通过类型校验避免意外数据导致报错:
{Array.isArray(idpData) ? idpData.map((idp: Foo) => (
  <option key={idp.id} value={idp.id} disabled={!hasEmailValid}>
    {idp.name}
  </option>
)) : null}

内容的提问来源于stack exchange,提问作者Thorsten Schöning

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:44:57