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
相关产品推荐
相关产品推荐

