React中Axios取数后调用map报错:Cannot read properties of undefined
解决React中Axios获取数据后map遍历报错
Cannot read properties of undefined (reading 'map') 问题场景
在React项目中使用Axios获取后端数据,尝试用map方法遍历数据渲染表格时,触发错误Cannot read properties of undefined (reading 'map')。推测原因是React先完成页面渲染再设置数据,尝试手动循环或forEach方法后仍出现类似错误,且每次运行会返回3条相同的错误信息。
原代码
import axios from "axios"; import { useState, useEffect } from "react"; // 原代码遗漏了该导入 function Table() { let [backendData, setData] = useState(); async function getData(){ await axios.get("table") .then(response => response.data) .then(data => setData(data)) } useEffect(() => { getData(); }, []) return( <div> <table> <thead> <tr> <th>Child's Name</th> <th>Child's Age</th> <th>Room No.</th> <th>Parent/Guardian Location</th> <th>Parent/Guardian Signature In</th> <th>Staff Signature In</th> <th>Parent/Guardian Signature Out</th> <th>Staff Signature Out</th> </tr> </thead> {backendData.map(child => { <tr key={child._id}> <td>{child.childName}</td> <td>{child.childAge}</td> <td>{child.roomNumber}</td> <td>temporary</td> <td><img src={child.parentSignature} /></td> <td><img src={child.parentSignature} /></td> <td><img src={child.parentSignature} /></td> <td><img src={child.parentSignature} /></td> </tr> })} </table> </div> ) } export default Table;
错误信息
Cannot read properties of undefined (reading 'map') TypeError: Cannot read properties of undefined (reading 'map') at Table (http://localhost:3000/static/js/bundle.js:2183:29) at renderWithHooks (http://localhost:3000/static/js/bundle.js:24189:22) at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:27475:17) at beginWork (http://localhost:3000/static/js/bundle.js:28771:20) at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:13781:18) at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:13825:20) at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:13882:35) at beginWork$1 (http://localhost:3000/static/js/bundle.js:33756:11) at performUnitOfWork (http://localhost:3000/static/js/bundle.js:33003:16) at workLoopSync (http://localhost:3000/static/js/bundle.js:32926:9) ERROR Cannot read properties of undefined (reading 'map') TypeError: Cannot read properties of undefined (reading 'map') at Table (http://localhost:3000/static/js/bundle.js:2183:29) at renderWithHooks (http://localhost:3000/static/js/bundle.js:24189:22) at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:27475:17) at beginWork (http://localhost:3000/static/js/bundle.js:28771:20) at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:13781:18) at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:13825:20) at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:13882:35) at beginWork$1 (http://localhost:3000/static/js/bundle.js:33756:11) at performUnitOfWork (http://localhost:3000/static/js/bundle.js:33003:16) at workLoopSync (http://localhost:3000/static/js/bundle.js:32926:9) ERROR Cannot read properties of undefined (reading 'map') TypeError: Cannot read properties of undefined (reading 'map') at Table (http://localhost:3000/static/js/bundle.js:2183:29) at renderWithHooks (http://localhost:3000/static/js/bundle.js:24189:22) at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:27475:17) at beginWork (http://localhost:3000/static/js/bundle.js:28771:20) at beginWork$1 (http://localhost:3000/static/js/bundle.js:33734:18) at performUnitOfWork (http://localhost:3000/static/js/bundle.js:33003:16) at workLoopSync (http://localhost:3000/static/js/bundle.js:32926:9) at renderRootSync (http://localhost:3000/static/js/bundle.js:32899:11) at recoverFromConcurrentError (http://localhost:3000/static/js/bundle.js:32391:24) at performConcurrentWorkOnRoot (http://localhost:3000/static/js/bundle.js:32303:26)
解决方案
1. 初始化状态为空数组
backendData初始值是undefined,组件第一次渲染时调用map会直接报错。将state初始化为空数组,确保第一次渲染时map能正常执行(空数组的map不会报错):
let [backendData, setData] = useState([]); // 改为空数组
2. 修复map函数的返回值
原代码中map的箭头函数用了大括号但没有return,导致遍历后不会生成任何JSX元素。可以改为小括号自动返回,或者手动添加return:
// 方式1:用小括号自动返回 {backendData.map(child => ( <tr key={child._id}> <td>{child.childName}</td> <td>{child.childAge}</td> <td>{child.roomNumber}</td> <td>temporary</td> <td><img src={child.parentSignature} /></td> <td><img src={child.parentSignature} /></td> <td><img src={child.parentSignature} /></td> <td><img src={child.parentSignature} /></td> </tr> ))} // 方式2:手动添加return {backendData.map(child => { return ( <tr key={child._id}> {/* ...内容同上 */} </tr> ) })}
3. 统一Axios的异步写法
不要同时混用await和.then(),两种写法选一种,避免逻辑混乱:
// 写法1:只用await async function getData(){ try { const response = await axios.get("table"); setData(response.data); } catch (error) { console.error("获取数据失败:", error); } } // 写法2:只用.then() function getData(){ axios.get("table") .then(response => setData(response.data)) .catch(error => console.error("获取数据失败:", error)); }
4. (可选)添加加载状态
可以增加一个加载状态,在数据未返回时显示加载提示,提升用户体验:
function Table() { let [backendData, setData] = useState([]); let [isLoading, setIsLoading] = useState(true); // 新增加载状态 async function getData(){ try { const response = await axios.get("table"); setData(response.data); } catch (error) { console.error("获取数据失败:", error); } finally { setIsLoading(false); // 无论成功失败都结束加载 } } useEffect(() => { getData(); }, []) if (isLoading) { return <div>加载中...</div>; // 加载时显示 } return( {/* 原表格内容 */} ) }
内容的提问来源于stack exchange,提问作者user16462824
相关产品推荐
相关产品推荐

