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

Next.js 13.4.3点击按钮后fetch请求无限循环问题求助

问题根源

你的代码存在两个核心问题导致fetch无限循环:

  1. 把async直接标记在React组件函数上,同时在组件顶层直接执行await fetch——React组件函数本身不能是异步函数(即使Next.js客户端组件允许,这种写法也会导致每次渲染都重新执行异步逻辑)。
  2. 点击按钮调用setShowModal(true)会触发组件状态更新,进而引发组件重渲染;每次重渲染时,组件顶层的fetch都会被重新执行,形成无限循环。
修复方案

方案一:用useEffect包裹异步请求(最直接修复)

将fetch逻辑放到useEffect中,通过依赖数组控制执行时机,确保只在组件挂载时执行一次:

"use client";
import { useState, useEffect } from "react";

export default function Home() {
  const [showModal, setShowModal] = useState(false);
  const [products, setProducts] = useState([]);

  useEffect(() => {
    const fetchProducts = async () => {
      const res = await fetch(`http://localhost:3000/products`, {
        cache: "no-store",
      });
      const data = await res.json();
      setProducts(data);
    };

    fetchProducts();
  }, []); // 空依赖数组:仅组件挂载时执行一次

  return (
    <>
      <button
        className="bg-pink-500 text-white active:bg-pink-600 font-bold uppercase text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
        type="button"
        onClick={() => setShowModal(true)}
      >
        Open regular modal
      </button>
      {/* 模态框代码... */}
    </>
  );
}

方案二:使用数据获取库(推荐复杂场景)

如果项目需要频繁处理数据获取、缓存或重新获取逻辑,建议用SWR或React Query这类专门的库,它们能自动避免重复请求:

"use client";
import { useState } from "react";
import useSWR from "swr";

const fetcher = async (url: string) => {
  const res = await fetch(url, { cache: "no-store" });
  return res.json();
};

export default function Home() {
  const [showModal, setShowModal] = useState(false);
  const { data: products } = useSWR(`http://localhost:3000/products`, fetcher);

  return (
    <>
      <button
        className="bg-pink-500 text-white active:bg-pink-600 font-bold uppercase text-sm px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 ease-linear transition-all duration-150"
        type="button"
        onClick={() => setShowModal(true)}
      >
        Open regular modal
      </button>
      {/* 模态框代码... */}
    </>
  );
}
关键提醒
  • 永远不要在React组件函数体的顶层直接执行异步请求,否则每次组件重渲染都会重复发起请求。
  • Next.js客户端组件中,async/await仅适用于特定场景(比如Server Components),客户端组件的异步逻辑必须通过useEffect或数据获取库管理。

内容的提问来源于stack exchange,提问作者Captai-N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:27:39