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

使用React Suspense与Await无法正常获取数据的技术问题

问题解决:使用和时仅获取到Response对象

你的核心问题是getBookmarks函数直接返回了fetch的Response对象,而非解析后的实际业务数据。

问题根源

fetch API调用成功后返回的是Response实例,它仅包含响应头、状态码等元数据,实际的业务数据存储在响应体中。当你仅用useLoaderData时,可能后续代码中手动做了解析操作;但使用defer配合Await时,Await会直接将Promise的最终结果(未解析的Response)传递给渲染函数,所以你看到的是Response对象而非期望的数据。

修复步骤

  1. 修改api.js中的数据解析逻辑
    在getBookmarks函数中添加响应体解析步骤(假设接口返回JSON格式数据):

    import config from './config'
    
    const apiUrl = config.apiUrl;
    const apiPort = config.apiPort;
    
    const joinUrl = (baseUrl, url) => {
      return `${baseUrl}/${url}`
    }
    
    const domain = `${apiUrl}:${apiPort}/api/bookmarks`;
    
    export async function getBookmarks(url = "") {
      url = joinUrl(domain, url)
      const response = await fetch(url);
      // 校验响应状态,提前捕获请求失败场景
      if (!response.ok) {
        throw new Error(`请求失败:${response.status}`);
      }
      // 解析JSON响应体,返回实际业务数据
      return await response.json();
    }
    
  2. 调整Home.jsx的渲染逻辑(可选)
    现在renderBookMarks接收的是解析后的业务数据,可以直接渲染:

    import React, { Suspense } from "react";
    import { getBookmarks } from "./api";
    import { useLoaderData, defer, Await } from "react-router-dom";
    
    export function loader() {
      return defer({ bookmarks: getBookmarks() });
    }
    
    export default function Home() {
      const dataPromise = useLoaderData();
    
      function renderBookMarks(bookmarks) {
        console.log(bookmarks); // 现在打印的是解析后的业务数据
        return (
          <ul className="bookmarks-list">
            {bookmarks.map(bookmark => (
              <li key={bookmark.id}>{bookmark.title}</li>
            ))}
          </ul>
        );
      }
    
      return (
        <div>
          <h2>Welcome to bookmarks</h2>
          <Suspense fallback={<h2>Loading...</h2>}>
            <Await resolve={dataPromise.bookmarks}>
              {renderBookMarks}
            </Await>
          </Suspense>
        </div>
      )
    }
    

补充说明

  • 如果接口返回文本格式数据,可将response.json()替换为response.text();
  • 添加response.ok校验能避免后续渲染逻辑处理无效的失败请求数据。

内容的提问来源于stack exchange,提问作者manjosh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:33:34