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

Next.js 14首屏加载时Suspense fallback在Safari失效(Chrome正常)

修复Safari中React Suspense不显示Fallback的问题

问题根源

直接将组件声明为async function并非React官方推荐的Suspense用法,这种写法的行为在不同浏览器中存在差异:Chrome会正确触发Suspense展示fallback,但Safari会等待异步组件完成数据获取后才渲染整个页面,导致Header和加载提示无法及时显示。

方案1:使用React 18+ use钩子配合Suspense兼容的数据获取

将数据逻辑与组件分离,通过抛出Promise让Suspense捕获,这是官方推荐的Suspense用法,能保证跨浏览器一致性:

import { Suspense, use } from "react";

// 单独的数据获取函数,抛出Promise供Suspense捕获
function fetchBlogPosts() {
  const dataPromise = fetch("https://httpbin.org/delay/5", { cache: "no-store" })
    .then(res => res.json());
  throw dataPromise;
}

function BlogPosts() {
  // 使用use钩子解析Promise
  const resjson = use(fetchBlogPosts());
  return <div>{resjson.url}</div>;
}

function Page() {
  return (
    <div>
      <h1>H E A D E R</h1>
      <div>
        <Suspense fallback={<div>fallback  ->  loading...</div>}>
          <BlogPosts />
        </Suspense>
      </div>
    </div>
  );
}

export default Page;

方案2:手动管理加载状态(兼容性更强)

如果需要兼容React 18以下版本,或者更精细控制加载逻辑,可以用useState和useEffect手动处理:

import { useState, useEffect } from "react";

function BlogPosts() {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    async function loadData() {
      try {
        const res = await fetch("https://httpbin.org/delay/5", { cache: "no-store" });
        const resjson = await res.json();
        setData(resjson);
      } finally {
        setIsLoading(false);
      }
    }
    loadData();
  }, []);

  // 手动返回加载提示
  if (isLoading) {
    return <div>fallback  ->  loading...</div>;
  }

  return <div>{data?.url}</div>;
}

function Page() {
  return (
    <div>
      <h1>H E A D E R</h1>
      <div>
        <BlogPosts />
      </div>
    </div>
  );
}

export default Page;

方案对比

  • 方案1更贴合React Suspense的设计理念,代码更简洁,但需要React 18及以上版本。
  • 方案2兼容性更好,不依赖Suspense特性,适合需要兼容多版本或自定义加载逻辑的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:52:41