MERN开发:在React前端渲染MongoDB嵌套消息列表的方案
React渲染MongoDB嵌套消息数组报错解决方案
需求说明
我正在学习MERN栈,需要在React前端页面展示MongoDB用户对象内嵌套存储的消息列表。
用到的MongoDB UserSchema定义
const userSchema = new mongoose.Schema({ name: { type: String, required: true, }, email: { type: String, required: true, }, phone: { type: Number, required: true, }, messages: [ { name: { type: String, required: true, }, email: { type: String, required: true, }, phone: { type: Number, required: true, }, message: { type: String, required: true, }, }, ], tokens: [ { token: { type: String, required: true, }, }, ], });
原有React Home.js代码
已经通过接口成功拿到完整的用户JSON数据,原有代码如下:
import React, { useState, useEffect } from "react"; const Home = () => { const [userName, setUserName] = useState({}); const [show, setShow] = useState(false); const userHome = async () => { try { const res = await fetch("/userdata", { method: "GET", headers: { "Content-Type": "application/json", }, }); const data = await res.json(); console.log(data); setUserName(data); setShow(true); } catch (err) { console.log(err); } }; useEffect(() => { userHome(); }, []); return ( <> <div className="page-wrap d-flex flex-row align-items-center"> <div className="container"> <div className="row justify-content-center"> <div className="col-md-12 text-center"> <span className="display-1 d-block"> <p> Welcome {show ? "Back!" : ""} </p> <h1>{userName.name}</h1> <h2> {show ? "What you want to do today?" : "Your own Portal.."} </h2> </span> <div className="mb-4 lead"> {show ? "" : "You need to register and login for accessing your profile."} </div> <div> <div>Messages:{userName[0].message}</div> </div> </div> </div> </div> </div> </> ); }; export default Home;
报错说明
最初尝试直接用 <div>Messages:{userName[0].message}</div>渲染消息列表,浏览器抛出错误:TypeError: Cannot read properties of undefined (reading 'message')。
报错原因
userName的初始值是空对象,接口请求为异步操作,首次渲染时还未拿到返回的用户数据,userName下不存在messages字段userName是单个用户对象,不是数组,不能用[0]的索引方式取值,消息数组是存储在userName的messages字段下
解决方案
删除原有错误代码,改用可选链配合map方法遍历消息数组即可,代码如下:
<div> {userName.messages?.map((msg1) => ( <li key={msg1._id}>{msg1.message}</li> ))} </div>
可选链?.的作用是当userName.messages为undefined时不会继续执行后续操作,避免抛出读取属性的错误,等接口请求完成数据更新后会自动重新渲染消息列表。
内容的提问来源于stack exchange,提问作者Zed
相关产品推荐
相关产品推荐

