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,直接写组件内正常 常见原因及排查方向
自定义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 },匹配组件调用方式 }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> ); }状态初始化或数据处理问题
- 检查
useState初始值:若初始值为undefined,组件首次渲染时projects就是undefined,需添加加载状态判断; - 检查fetch响应:确认后端返回的是纯数组,若返回
{ data: [...] }结构,需取data字段再设置状态。
- 检查
内容的提问来源于stack exchange,提问作者user824624
相关产品推荐
相关产品推荐

