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

Next.js 13获取服务端数据后array.map报错及自定义Hook失效问题

问题1:服务端渲染中自定义async hook导致array.map is not a function

原因

React自定义hook不能是异步函数(async),所有hook必须在组件顶层同步调用。你写的async useProjects返回的是Promise而非直接的数组数据——即便控制台能打印出数组,那也是Promise内部的结果,但组件拿到的是Promise对象,自然调用map会报错。

另外,Next.js 13 App Router中page.tsx默认是服务端组件,服务端组件本身支持异步,但无需封装成async hook,直接在组件内异步取数即可。

解决方法

直接在服务端组件page.tsx中异步获取数据:

// app/team/page.tsx
export default async function TeamPage() {
  const res = await fetch('/api/projects', { cache: 'no-store' }); // 根据需求调整缓存策略
  const projects = await res.json();

  return (
    <div>
      {projects.map(project => (
        <div key={project.id}>{project.name}</div>
      ))}
    </div>
  );
}

问题2:客户端自定义hook调用时projects为undefined,直接写组件内正常

常见原因及排查方向

  1. 自定义hook返回值错误
    检查hook是否正确返回状态值,避免漏写返回逻辑:
    错误写法:

    // 错误的自定义hook
    function useProjects() {
      const [projects, setProjects] = useState<Project[] | undefined>();
      useEffect(() => {
        async function fetchData() {
          const res = await fetch('/api/projects');
          const data = await res.json();
          setProjects(data);
        }
        fetchData();
      }, []);
      // 未返回projects,组件调用时拿到undefined
    }
    

    正确写法:

    // 正确的自定义hook
    function useProjects() {
      const [projects, setProjects] = useState<Project[] | undefined>();
      useEffect(() => {
        async function fetchData() {
          const res = await fetch('/api/projects');
          const data = await res.json();
          setProjects(data);
        }
        fetchData();
      }, []);
      return projects; // 或返回{ projects },匹配组件调用方式
    }
    
  2. Team组件未标记为客户端组件
    Next.js 13 App Router中,使用useState/useEffect等客户端hook的组件,必须添加'use client'指令。若Team是服务端组件,调用含客户端hook的自定义hook会导致状态无法正常初始化,projects始终为undefined。
    解决:在Team组件顶部添加指令:

    // Team组件文件顶部
    'use client';
    
    import { useProjects } from './useProjects';
    
    export default function Team() {
      const projects = useProjects();
      return projects ? (
        <div>{projects.map(...)}</div>
      ) : (
        <div>Loading...</div>
      );
    }
    
  3. 状态初始化或数据处理问题

    • 检查useState初始值:若初始值为undefined,组件首次渲染时projects就是undefined,需添加加载状态判断;
    • 检查fetch响应:确认后端返回的是纯数组,若返回{ data: [...] }结构,需取data字段再设置状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:01:23