Next.js App Router下TypeScript组件Props类型错误与初始化求助
问题分析与解决方案
错误原因
你遇到的TypeScript错误是因为Next.js App Router的page.tsx组件不能接收自定义Props类型。App Router对页面组件的props有固定校验规则,仅允许接收Next.js提供的内置props(如params、searchParams),自定义Props类型不符合构建时的校验逻辑,因此npm run build报错。
可行解决方案
方案1:使用App Router服务器组件直接获取数据(推荐)
App Router默认支持服务器组件,可以在组件顶层直接用async/await获取数据,无需useState或useEffect,数据会在服务器端(构建时或请求时)获取,然后直接传递给子组件。
修改src/app/page.tsx如下:
// src/app/page.tsx // 服务器组件无需'use client',支持顶层async/await export default async function Home() { // 直接在顶层获取所有数据 const pageInfo = await fetchPageInfo(); const experiences = await fetchExperiences(); const skills = await fetchSkills(); const projects = await fetchProjects(); const socials = await fetchSocials(); // 将数据作为props传递给子组件 return ( <main> <Header pageInfo={pageInfo} socials={socials} /> <ExperienceSection experiences={experiences} /> <SkillsSection skills={skills} /> <ProjectsSection projects={projects} /> </main> ); }
- 优势:无需客户端状态管理,服务器端获取数据性能更好,构建时无类型错误。
- 若子组件需要交互(如使用hooks),只需在子组件顶部添加
'use client'指令即可。
方案2:客户端组件结合SWR/React Query管理数据
如果需要在客户端处理数据更新或缓存,可以用数据请求库(如SWR),搭配服务器组件预传初始数据:
- 服务器组件预获取初始数据:
// src/app/page.tsx(服务器组件) export default async function Home() { // 预获取初始数据 const initialData = { pageInfo: await fetchPageInfo(), experiences: await fetchExperiences(), skills: await fetchSkills(), projects: await fetchProjects(), socials: await fetchSocials(), }; // 传递给客户端组件 return <HomeClient initialData={initialData} />; }
- 客户端组件用SWR管理数据:
// src/app/components/HomeClient.tsx 'use client'; import useSWR from 'swr'; type InitialData = { pageInfo: PageInfo; experiences: Experience[]; skills: Skill[]; projects: Project[]; socials: Social[]; }; type Props = { initialData: InitialData }; // 统一fetcher函数 const fetcher = async (key: string) => { switch (key) { case 'pageInfo': return fetchPageInfo(); case 'experiences': return fetchExperiences(); case 'skills': return fetchSkills(); case 'projects': return fetchProjects(); case 'socials': return fetchSocials(); default: throw new Error('Invalid fetch key'); } }; export default function HomeClient({ initialData }: Props) { // 用SWR管理数据,支持缓存、自动重新验证 const { data: pageInfo } = useSWR('pageInfo', fetcher, { initialData: initialData.pageInfo }); const { data: experiences } = useSWR('experiences', fetcher, { initialData: initialData.experiences }); const { data: skills } = useSWR('skills', fetcher, { initialData: initialData.skills }); const { data: projects } = useSWR('projects', fetcher, { initialData: initialData.projects }); const { data: socials } = useSWR('socials', fetcher, { initialData: initialData.socials }); return ( <main> {/* 渲染交互内容 */} </main> ); }
方案3:回到Pages Router解决404问题
如果你想继续使用getStaticProps/getServerSideProps,需要注意Pages Router的文件命名规则:
- 首页必须放在
src/pages/index.tsx(而非page.tsx),否则会出现404。 - 正确写法示例:
// src/pages/index.tsx import { GetStaticProps } from 'next'; import { useState } from 'react'; type Props = { pageInfo: PageInfo; experiences: Experience[]; skills: Skill[]; projects: Project[]; socials: Social[]; }; export default function Home(props: Props) { // 若需要修改状态,从props初始化useState const [pageInfoState, setPageInfoState] = useState(props.pageInfo); const [experiencesState, setExperiencesState] = useState(props.experiences); // 将数据传递给子组件 return ( <main> <Header pageInfo={pageInfoState} /> </main> ); } // 使用getStaticProps在构建时获取数据 export const getStaticProps: GetStaticProps<Props> = async () => { const pageInfo = await fetchPageInfo(); const experiences = await fetchExperiences(); const skills = await fetchSkills(); const projects = await fetchProjects(); const socials = await fetchSocials(); return { props: { pageInfo, experiences, skills, projects, socials }, revalidate: 86400, // 可选:每天重新生成页面 }; };
初始化props并传递给子组件的通用方法
- App Router:服务器组件获取数据后直接作为props传递给子组件;客户端组件通过父组件(服务器或客户端)接收数据,或用SWR/React Query自主获取。
- Pages Router:通过
getStaticProps/getServerSideProps获取数据传递给page组件,再由page组件传递给子组件,若需要修改状态则用useState(props.xxx)初始化。
内容的提问来源于stack exchange,提问作者Jboy-49
相关产品推荐
相关产品推荐

