React中如何访问JSON嵌套对象,展示doctor与roomName数据
问题描述
我需要在React项目中访问给定的JSON数据,将doctor对象的内部元素以及roomName值展示在页面上。我已创建state用于存储相关对象,希望遍历并展示其值,但目前仅能展示allReservations数组中的所有对象。请问如何正确访问doctor对象及其内部元素?
JSON数据
{ "totalReservations": 1, "allReservations": [ { "_id": "62d5f88672dd3fadbeeee7d5", "userId": { "_id": "62cf836dbbb2ddfdcca4df4d", "image": "https://res.cloudinary.com/devsalem/image/upload/v1657766765/YOU/fuiiwkvdxwgczpfkv4d9.jpg", "name": "Hassan Ibrahim", "mobilePhone": "01010644258", "gender": "male", "email": "nohahassan497@yahoo.com", "birthDate": "1991-06-04", "trustContact": "01016166161", "contactRelation": "mom", "sessions": [ "Individual Session" ] }, "doctor": { "_id": "62cf8f75bb6b1eb825e8ab93", "image": "https://res.cloudinary.com/devsalem/image/upload/v1657769832/YOU/umf1hkh7mjtasd5zy0vr.jpg", "name": "ruba hamed", "mobilePhone": "01222990000", "gender": "female", "email": "drruba1111@gmail.com", "birthDate": "22/4/1980", "languages": [ "english, spanish, arabic" ], "licIssuedDate": "22/2/1998", "licExpiryDate": "22/2/1999", "profession": "therapist", "sessionPrice": "400" }, "startDate": "12:00 pm", "date": "2022-07-26", "roomName": "6feb87ad-b0cb-4877-a5ed-44e0c1f79fd8" } ] }
当前代码
import React, { Fragment } from "react"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import axios from "axios"; import './c-session.css'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPhone, faCalendar } from "@fortawesome/free-solid-svg-icons"; import clientimg from '../../../pictures/0_GettyImages-1333254883.png'; import clientname from '../../../pictures/icons8-name-tag-48.png'; import clientdate from '../../../pictures/Icon material-date-range.png'; import clientsession from '../../../pictures/icons8-question-and-answer-session-with-speech-bubble-48.png'; import clientcall from '../../../pictures/icons8-video-call-64.png'; const CSessionFrag = (props) => { console.log('hi noha ana l frag'); const navigate = useNavigate(); const token = props.token; const [date, setDate] = useState(); const doctors = {}; const [doctorsArray, setDoctorsArray] = useState(doctors); useEffect(() => { axios.get('/reservation', { headers: { 'token': token } }) .then(res => { console.log('sesssssssssssion fragment of doctorProfile response', res.data.allReservations[0].doctor); console.log('sesssssssssssion fragment of doctorProfile response', res.data.allReservations[0].roomName); const reserv = res.data.allReservations; const allData = reserv[0]; setDoctorsArray(allData); console.log('l arayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', doctorsArray); // setImmediate(res.data.allReservations.date); }).catch(e => { console.log('sesion errooooooor', e); }) }, []); return ( <Fragment> { Object.keys((doctorsArray)).map((key, doctor) => ( <Fragment key={doctorsArray[key]._id} > <div className="c-session_card"> <div className="c-session_card_top"> <img className="c-session_card_top_img" src={doctorsArray[key].image} /> </div> <div className="c-session_card_middle"> <p className="c-session_card_txt" id="c-session_card_name"> <img className="c-session_card_icon" id="c-session_name" src={clientname} /> {doctorsArray[key].name} </p> <p className="c-session_card_txt" > <img className="c-session_card_icon" src={clientcall} /> {doctorsArray[key].profession} </p> <p className="c-session_card_txt" id="c-session_date_p" > <img className="c-session_card_icon" id="c-session_date" src={clientdate} /> {date} </p> <p className="c-session_card_txt" id="c-session_date_p" > <img className="c-session_card_icon" id="c-session_date" src={clientdate} /> {doctorsArray[key].sesionPrice} </p> </div> <div className="c-session_card_bottom"> <button className="c-session_card_bottom_btn" id="c-session_profile_btn" onClick={() => { navigate('/doctorprofile', { state: { docId: doctorsArray[key].id } }) }}>Profile</button> <button className="c-session_card_bottom_btn" id="c-session_call_btn" onClick={() => navigate('/startsession', { state: { docId: doctorsArray[key].id } })}> <FontAwesomeIcon icon={faPhone} id="c-session_call_btn_icon" /> Start Session </button> </div> </div> </Fragment > )) } </Fragment > ); } export default CSessionFrag;
解决方案
你的代码存在几个核心问题,导致无法正确访问doctor对象和roomName,以下是修正方案:
关键问题分析
- State存储与遍历逻辑错误:你把单个预约对象存在
doctorsArray中,却用Object.keys().map遍历该对象的所有属性(如_id、userId等),这完全偏离了展示医生信息的需求。 - 属性访问路径错误:
doctor是预约对象的子属性,正确路径应为reservation.doctor.xxx,而非遍历预约对象的key来访问。 - 细节错误:拼写错误
sesionPrice应为sessionPrice;数据中的ID字段是_id而非id;datestate未赋值。
修改后的代码
import React, { Fragment } from "react"; import { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import axios from "axios"; import './c-session.css'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faPhone, faCalendar } from "@fortawesome/free-solid-svg-icons"; import clientimg from '../../../pictures/0_GettyImages-1333254883.png'; import clientname from '../../../pictures/icons8-name-tag-48.png'; import clientdate from '../../../pictures/Icon material-date-range.png'; import clientsession from '../../../pictures/icons8-question-and-answer-session-with-speech-bubble-48.png'; import clientcall from '../../../pictures/icons8-video-call-64.png'; const CSessionFrag = (props) => { const navigate = useNavigate(); const token = props.token; // 初始化state为null,避免渲染空值报错 const [reservation, setReservation] = useState(null); useEffect(() => { axios.get('/reservation', { headers: { 'token': token } }) .then(res => { const firstReservation = res.data.allReservations[0]; setReservation(firstReservation); }).catch(e => { console.log('session error', e); }) }, [token]); // 添加token到依赖,避免闭包问题 // 加载状态判断 if (!reservation) { return <div>加载中...</div>; } // 解构属性,简化后续访问 const { doctor, roomName, date, startDate } = reservation; return ( <Fragment> <div className="c-session_card"> <div className="c-session_card_top"> <img className="c-session_card_top_img" src={doctor.image} alt={doctor.name} /> </div> <div className="c-session_card_middle"> <p className="c-session_card_txt" id="c-session_card_name"> <img className="c-session_card_icon" id="c-session_name" src={clientname} /> {doctor.name} </p> <p className="c-session_card_txt" > <img className="c-session_card_icon" src={clientcall} /> {doctor.profession} </p> <p className="c-session_card_txt" id="c-session_date_p" > <img className="c-session_card_icon" id="c-session_date" src={clientdate} /> {date} {startDate} </p> <p className="c-session_card_txt" id="c-session_date_p" > <img className="c-session_card_icon" id="c-session_date" src={clientdate} /> {doctor.sessionPrice} </p> <p className="c-session_card_txt" > <img className="c-session_card_icon" src={clientdate} /> 房间号: {roomName} </p> </div> <div className="c-session_card_bottom"> <button className="c-session_card_bottom_btn" id="c-session_profile_btn" onClick={() => navigate('/doctorprofile', { state: { docId: doctor._id } })}>Profile</button> <button className="c-session_card_bottom_btn" id="c-session_call_btn" onClick={() => navigate('/startsession', { state: { docId: doctor._id, roomName } })}> <FontAwesomeIcon icon={faPhone} id="c-session_call_btn_icon" /> Start Session </button> </div> </div> </Fragment > ); } export default CSessionFrag;
修改说明
- 将state命名为
reservation,准确反映存储的是单个预约对象; - 添加加载状态,避免初始渲染时的空值报错;
- 通过解构直接获取
doctor、roomName等属性,简化访问路径; - 修正拼写和ID字段的错误;
- 将
token加入useEffect依赖数组,确保token变化时重新请求数据; - 把
roomName传递到会话页面,方便后续使用。
内容的提问来源于stack exchange,提问作者Noha derwa
相关产品推荐
相关产品推荐

