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

NextJS中使用Stripe API结账会话的加载屏问题

解决NextJS跳转Stripe支付页时的空白白屏问题

问题原因分析

你之前的代码把setLoading(true)放在了getCheckoutStripeLink的then回调里,这意味着加载状态要等接口请求完成后才会触发,但空白白屏恰恰出现在接口请求的等待阶段,所以加载组件根本来不及显示。另外,用NextJS的router.push跳转外部链接(Stripe地址)并非最优选择,它会经过内部路由处理逻辑,可能增加不必要的延迟。

解决方案

1. 立即触发加载状态 + 正确跳转外部链接

修改按钮点击逻辑,先设置加载状态,再调用接口,接口返回后用window.location.href直接跳转外部链接:

import { useContext } from "react";
import { LoadingContext } from "../contexts/LoadingContext"; // 你的加载上下文

// ...

const { setLoading } = useContext(LoadingContext);

// ...

<Button
  onClick={() => {
    // 点击后立即开启加载状态
    setLoading(true);
    getCheckoutStripeLink(profile)
      .then((payLink) => {
        // 用window.location.href跳转外部链接,替代router.push
        window.location.href = payLink;
      })
      .catch((error) => {
        // 请求失败时关闭加载状态,避免一直显示加载
        setLoading(false);
        console.error("获取支付链接失败:", error);
        // 可添加错误提示,比如弹出Toast
      });
  }}
>
  My billing
</Button>

2. (可选)添加局部按钮加载状态

除了全局加载屏,还可以给按钮本身添加加载状态,避免用户重复点击,体验更直观:

import { useContext, useState } from "react";
import { LoadingContext } from "../contexts/LoadingContext";

// ...

const { setLoading } = useContext(LoadingContext);
const [isButtonLoading, setIsButtonLoading] = useState(false);

// ...

<Button
  onClick={() => {
    if (isButtonLoading) return;
    setIsButtonLoading(true);
    setLoading(true);
    
    getCheckoutStripeLink(profile)
      .then((payLink) => {
        window.location.href = payLink;
      })
      .catch((error) => {
        setIsButtonLoading(false);
        setLoading(false);
        console.error("获取支付链接失败:", error);
      });
  }}
  disabled={isButtonLoading}
>
  {isButtonLoading ? "加载中..." : "My billing"}
</Button>

3. 确认上下文状态传递正确

确保_app.tsx中的加载上下文Provider正确包裹所有页面组件,比如:

import { LoadingContextProvider } from "../contexts/LoadingContext";
import Loading from "../components/Loading";
import { useState } from "react";

function MyApp({ Component, pageProps }) {
  const [loading, setLoading] = useState(false);
  const [loadingAuth, setLoadingAuth] = useState(false);

  if (loading || loadingAuth) {
    console.debug("LOADING on app");
    return <Loading />;
  }

  return (
    <LoadingContextProvider value={{ loading, setLoading }}>
      <Component {...pageProps} />
    </LoadingContextProvider>
  );
}

export default MyApp;

关键说明

  • 外部链接跳转优先用window.location.href,跳过NextJS内部路由处理,减少延迟。
  • 加载状态必须在接口请求前设置,才能覆盖等待接口响应的空白期。
  • 一定要处理接口请求失败的情况,重置加载状态,避免页面一直处于加载状态。

内容的提问来源于stack exchange,提问作者engineer-x

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:07:45