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

Next.js(TypeScript)结合Mongoose时页面无法渲染学生信息

问题:接口返回学生信息可在控制台打印,但页面无法渲染

我尝试展示接口返回的学生信息,终端通过console.log能看到正确数据(返回为数组),但页面无法渲染该信息。技术栈是Next.js(TypeScript)+Mongoose,相关代码如下:

type Student = {
  _id: string;
  firstname: string;
  lastname: string;
  matricno: string;
};

function DashBoard() {
  const [student, setStudent] = useState<Student>();

  //this works
  // console.log(getCookie("user"))

  const showinfo = async () => {
    const token = getCookie('user');
    const body = {
      _id: token,
    };

    const response = (await fetch(
      'http://localhost:3000/api/student/fetchStudent',
      { method: 'POST', body: JSON.stringify(body) }
    ).then((res) => res.json())) as Student;

    console.log(JSON.stringify(response, ['student', 'firstname'])); //displays right information

    setStudent(response);

    const user = JSON.stringify(response, ['student', 'lastname']);

    console.log(user); //displays right information
  };

  useEffect(() => {
    showinfo();
  }, []);

  return (
    <StuLayout>
      <>
        <Header title='dashboard' />
        <div className='text-red-500 text-3xl'>
          welcome {student?.firstname}
        </div>
      </>
    </StuLayout>
  );
}

export default DashBoard;

问题分析与解决方案

核心问题

从你打印日志的代码JSON.stringify(response, ['student', 'firstname'])能看出,接口返回的实际学生数据是嵌套在student字段里的,但你直接把整个response对象赋值给了student状态。而你的Student类型定义里并没有这个嵌套字段,所以页面上student?.firstname根本取不到值,自然渲染不出来。

另外你提到接口返回的是数组,但代码里把response断言成了单个Student类型,这也是需要修正的点。


解决方案1:取出嵌套的student字段赋值

如果接口返回结构是{ student: Student },直接修改setStudent的赋值逻辑:

// 把整个response改成response.student
setStudent(response.student);

解决方案2:修正类型定义(匹配接口返回结构)

如果接口返回的结构本身就包含顶层student字段,调整类型定义更规范:

type Student = {
  _id: string;
  firstname: string;
  lastname: string;
  matricno: string;
};

// 新增接口返回的类型
type StudentApiResponse = {
  student: Student;
};

然后请求时断言正确的类型:

const response = (await fetch(
  'http://localhost:3000/api/student/fetchStudent',
  { 
    method: 'POST', 
    body: JSON.stringify(body),
    headers: { 'Content-Type': 'application/json' } // 补充请求头,确保后端解析正常
  }
).then(res => res.json())) as StudentApiResponse;

setStudent(response.student);

额外处理:接口返回数组的情况

你明确说接口返回的是数组,那状态和渲染逻辑要对应调整:

// 状态改成数组类型,初始化空数组
const [students, setStudents] = useState<Student[]>([]);

const showinfo = async () => {
  // ...其他代码
  // 断言成数组类型
  const response = (await fetch(...).then(res => res.json())) as Student[];
  setStudents(response);
};

// 渲染时遍历数组
return (
  <StuLayout>
    <>
      <Header title='dashboard' />
      {students.map(student => (
        <div key={student._id} className='text-red-500 text-3xl'>
          welcome {student.firstname}
        </div>
      ))}
    </>
  </StuLayout>
);

补充建议

你的fetch请求没加Content-Type: application/json头,虽然当前能拿到数据,但可能导致后端解析异常,建议加上这个头,避免后续出现问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:18:38