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

Next.js动态Slug组件导入JS对象列表及取值异常排查

Next.js动态路由项目详情页undefined报错解决

问题分析

核心问题是服务端渲染(SSR)阶段router.query.slug未初始化,导致:

  • VS Code终端(服务端)打印project为undefined:服务端渲染时无客户端路由信息,router.query.slug为空,转数字后得到NaN,projectlist[NaN]无法匹配到对应项目
  • 浏览器控制台能显示项目详情:客户端hydration完成后,路由信息加载完毕,projectid正确获取,可匹配到对应项目
  • 访问project.name时报错:服务端渲染阶段project为undefined,读取其属性触发TypeError

另外ProjectDetail组件的参数解构存在语法错误,会影响参数的正确接收。

解决方案

1. 修正组件参数解构语法

将错误的参数解构写法改为正确形式:

// 错误写法
const ProjectDetail = ({projectid}=props) => { ... }

// 正确写法二选一:
// 写法1:直接解构参数
const ProjectDetail = ({ projectid }) => { ... }
// 写法2:先接收props再解构
const ProjectDetail = (props) => {
  const { projectid } = props;
  ...
}

2. 等待路由就绪后渲染详情组件

在ProjectPage中利用router.isReady判断路由是否初始化完成,避免服务端渲染时传递无效的projectid:

import { useRouter } from 'next/router';
import ProjectDetail from '../../components/projectdetails';
import '../../styles/globals.css'

const ProjectPage = () => {
  const router = useRouter();
  
  // 路由未就绪时,返回加载提示
  if (!router.isReady) {
    return <div>加载中...</div>;
  }
  
  const projectid = parseInt(router.query.slug, 10);
  return (
    <>
      <ProjectDetail projectid={projectid} />
    </>
  );
};

export default ProjectPage;

3. 给ProjectDetail添加空值保护

即使路由就绪,也要处理projectid对应项目不存在的情况,避免报错:

'use client';
import { Box, Paper, Typography } from '@mui/material';
import projectlist from '../utility/projectlist';

const ProjectDetail = ({ projectid }) => {
  const project = projectlist[projectid];
  
  // 项目不存在时返回提示
  if (!project) {
    return <div>项目不存在</div>;
  }
  
  console.log(project.name);
  // const images = [...project.screenshot];
  
  return (
    <div>
      <Box>
        <Typography variant="h4">{project.name}</Typography>
        {/* 渲染其他项目内容 */}
      </Box>
    </div>
  );
};

export default ProjectDetail;

4. 进阶方案:使用静态预渲染(推荐)

如果项目列表是静态数据,用getStaticPaths和getStaticProps预渲染所有详情页,彻底避免路由初始化问题:

修改/pages/projects/[slug].js:

import ProjectDetail from '../../components/projectdetails';
import '../../styles/globals.css'
import projectlist from '../../utility/projectlist';

// 生成所有可能的动态路由路径
export async function getStaticPaths() {
  const paths = projectlist.map((_, index) => ({
    params: { slug: index.toString() },
  }));
  
  return { paths, fallback: false };
}

// 获取对应项目的数据
export async function getStaticProps({ params }) {
  const projectid = parseInt(params.slug, 10);
  const project = projectlist[projectid];
  
  return {
    props: { project },
  };
}

const ProjectPage = ({ project }) => {
  if (!project) {
    return <div>项目不存在</div>;
  }
  
  return (
    <>
      <ProjectDetail project={project} />
    </>
  );
};

export default ProjectPage;

修改ProjectDetail组件直接接收project:

'use client';
import { Box, Paper, Typography } from '@mui/material';

const ProjectDetail = ({ project }) => {
  console.log(project.name);
  // const images = [...project.screenshot];
  
  return (
    <div>
      <Box>
        <Typography variant="h4">{project.name}</Typography>
        {/* 渲染其他项目内容 */}
      </Box>
    </div>
  );
};

export default ProjectDetail;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:45:36