访问/programari路由提示Cannot read property 'map' of undefined如何处理?
问题根因
- 第二个
useEffect未配置依赖数组,会在组件每次渲染后重复触发请求,极易引发时序异常 - fetch请求仅在响应状态正常时返回json数据,若请求失败、响应码非200时,第一个
then没有返回值,后续拿到的jsonRes为undefined,执行setValues(undefined)后values状态变为undefined,调用map方法直接触发报错 - 未校验后端返回值格式,若
/programari接口返回的不是数组类型(比如被外层对象包裹、返回空值等),也会导致values调用map失败 - 遍历数组时未设置唯一key,也会触发React的渲染警告
修复步骤
- 给fetch数据的useEffect添加依赖数组:如果仅需要组件挂载时拉取一次数据,填入空数组
[];如果需要依赖其他变量触发请求,把对应变量加入依赖列表 - 完善fetch的错误处理逻辑,请求异常时给values设置默认空数组,避免状态变为undefined
- 渲染时用可选链调用map,或者提前判断values是数组再执行遍历
- 校验后端接口返回值,确保返回的是预期的数组结构
- 给遍历生成的tr元素添加唯一key属性
修改后参考代码
import Header from "../../header/Header"; import React, { useState, useEffect } from "react"; import axios from "axios"; import { useSelector, useDispatch } from "react-redux"; import { fetchAllUsers, dispatchGetAllUsers, } from "../../../redux/actions/usersAction"; function Profile() { const auth = useSelector((state) => state.auth); const token = useSelector((state) => state.token); const [values, setValues] = useState([ { date: "", email: "", firstName: "", hour: "", lastName: "", phoneNumber: "", }, ]); const { user, isAdmin } = auth; const [callback, setCallback] = useState(false); const dispatch = useDispatch(); useEffect(() => { if (isAdmin) { fetchAllUsers(token).then((res) => { dispatch(dispatchGetAllUsers(res)); }); } }, [token, isAdmin, dispatch, callback]); // 修复后的useEffect useEffect(() => { fetch("/programari") .then((res) => { if (res.ok) { return res.json(); } throw new Error('响应状态异常') }) .then((jsonRes) => { // 校验返回值为数组再赋值 if (Array.isArray(jsonRes)) { setValues(jsonRes) } else { setValues([]) } }) .catch(err => { console.error('拉取预约数据失败:', err) setValues([]) }) }, []); // 空依赖代表仅组件挂载时请求一次 return ( <> <div> <div className="App"> <Header /> <div className="profile_page"> <h2> {isAdmin ? "Programari" : "Ne bucuram sa va avem client fidel"} </h2> <div style={{ overflowX: "auto" }}> <table className="customers"> <thead> <tr> <th>Nume</th> <th>Prenume</th> <th>Telefon</th> <th>Email</th> <th>Data</th> <th>Ora</th> </tr> </thead> <tbody> {/* 可选链避免undefined调用map,添加唯一key */} {values?.map((value, index) => ( <tr key={value.phoneNumber || index}> <td>{value.date}</td> <td>{value.email}</td> <td>{value.firstName}</td> <td>{value.hour}</td> <td>{value.lastName}</td> <td>{value.phoneNumber}</td> </tr> ))} </tbody> </table> </div> </div> </div> </div> </> ); } export default Profile;
内容的提问来源于stack exchange,提问作者viorel Grigoras
相关产品推荐
相关产品推荐

