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

Next.js中GET请求重复执行6次且初始值为undefined的问题排查

问题:Next.js中/api/prompt请求重复执行6次且初始post值为undefined

我在开发Next.js教程应用时遇到两个问题:

  1. 页面的GET请求/api/prompt重复执行了6次;
  2. 前两次传递给PromptCard组件的post值为undefined,导致组件渲染失败。

背景信息

MongoDB Atlas中仅有1条Prompt集合文档,结构如下:

{
    "_id": "65283e66e24b46a5cc3e0063",
    "prompt": "As a software engineer, propose some troubleshooting techniques I can use to debug React/Next.js hydration errors.",
    "tag": "web development",
    "__v": 0
}

API代码(/api/prompt/route.js)

import { connectToDb } from "@utils/database";
import Prompt from "@models/prompt";

export const GET = async (req, res) => {
  try {
    await connectToDb();
    const prompts = await Prompt.find({}).populate('creator')
    return new Response(JSON.stringify(prompts), {status: 200})
  } catch(error) {
    return new Response('Failed to fetch prompts', {status: 500})
  }
}

客户端组件代码(Feed.jsx)

'use client';

import { useState, useEffect } from "react"

const PromptCard = ({post, handleTagClick, handleEdit, handleDelete}) => {
  console.log(post)
  return (
    <div className="prompt_card">
    </div>
  )
}

const PromptCardList = ({ data, handleTagClick }) => {
  return (
    <div className="mt-16 prompt_layout">
      <PromptCard post={data[0]}/>
    </div>
  )
}

const Feed = () => {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchPosts = async () => {
      const response = await fetch("/api/prompt");
      const data = await response.json();
      setPosts(data);
    };
    fetchPosts();
  }, []);

  return (
    <section className='feed'>
      <PromptCardList data={posts} handleTagClick={{}} handleEdit={{}} handleDelete={{}} />
    </section>
  )
}

export default Feed;

排查方向与解决建议

1. 解决post初始为undefined的问题

  • 组件首次渲染时,posts初始值是空数组,data[0]自然是undefined。给PromptCard加条件渲染,确保有数据再渲染:
    const PromptCard = ({post, handleTagClick, handleEdit, handleDelete}) => {
      if (!post) return null; // 也可以替换为加载状态组件
      console.log(post)
      return (
        <div className="prompt_card">
        </div>
      )
    }
    
  • 或者在PromptCardList里先判断数据是否存在:
    const PromptCardList = ({ data, handleTagClick }) => {
      return (
        <div className="mt-16 prompt_layout">
          {data.length > 0 && <PromptCard post={data[0]}/>}
        </div>
      )
    }
    

2. 排查请求重复执行的问题

  • 检查React Strict Mode:Next.js开发环境默认开启Strict Mode,会重复执行useEffect、组件渲染等操作(通常是2次)。如果请求次数达6次,先确认Feed组件是否被父组件重复挂载——检查父组件的渲染逻辑或路由配置。
  • 查看请求发起者:打开浏览器控制台Network标签,查看每个/api/prompt请求的Initiator字段,定位触发请求的代码段,判断是否有多个地方调用了fetch。
  • 移除不必要的populate操作:你的MongoDB文档中没有creator字段,populate('creator')会尝试关联但无数据,虽然不影响返回,但可能引发额外查询逻辑,暂时移除该操作后观察请求次数变化。
  • 检查组件重复渲染:在Feed组件中添加console.log('Feed rendered'),查看组件是否被多次渲染,若多次渲染则排查父组件的状态变化或路由逻辑。
  • 显式设置fetch缓存:Next.js客户端组件中fetch默认不缓存,可显式设置缓存模式减少重复请求:
    const response = await fetch("/api/prompt", { cache: 'force-cache' });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 19:32:40