React中使用.map方法报错:Cannot read properties of undefined (reading 'map')
React中使用
.map()时报错:Uncaught TypeError: Cannot read properties of undefined (reading 'map') 报错信息:"Uncaught TypeError: Cannot read properties of undefined (reading 'map')"
推测问题是JSON数据被当作对象而非数组传递,添加数组检查逻辑后仍未解决,以下是相关代码:
Properties组件代码
import React from 'react' import SearchBar from '../../components/SearchBar/SearchBar' import './Properties.css' import useProperties from '../../hooks/useProperties' import { PuffLoader } from 'react-spinners' import PropertyCard from '../../components/PropertyCard/PropertyCard' const Properties = () => { const { data, isError, isLoading } = useProperties() if (isError) { return ( <div className="wrapper"> <span>Error while fetching data</span> </div> ) } if (isLoading) { return ( <div className="wrapper flexCenter" style={{ height: "60vh" }}> <PuffLoader height="80" width="80" radius={1} color='#4066ff' aria-label='puff-loading' /> </div> ) } return ( <div className="wrapper"> <div className="flexColCenter paddings innerWidth properties-container"> <SearchBar /> <div className="paddings flexCenter properties"> { data.map((card, i) => (<PropertyCard card={card} key={i} />)) } </div> </div> </div> ) } export default Properties
JSON数据示例
[ { "_id": { "$oid": "64392d39dfd90fb29e464fb7" }, "title": "Sunny Meadow Cottage", "description": "Massive opportunity to build your dream home at the base of Mummy Mountain in the 3 C's school district. Home is currently updated and very livable if your plans are to build at a later date.* Bonus * to live hillside without hillside restrictions in the town of PV. Run don't walk to capture this needle in a hay stack.", "price": 6000, "address": "Street 1", "city": "Chicago", "country": "US", "image": "https://images.pexels.com/photos/7031406/pexels-photo-7031406.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", "userEmail": "mukhtarhamza294@gmail.com", "createdAt": { "$date": "2023-04-14T10:38:48.762Z" }, "updatedAt": { "$date": "2023-04-14T10:38:48.762Z" }, "facilities": { "bathrooms": "2", "parking": "1", "bedrooms": "5" } }, { "_id": { "$oid": "64392e0bdfd90fb29e464fbc" }, "title": "Coastal Breeze Villa", "description": "Massive opportunity to build your dream home at the base of Mummy Mountain in the 3 C's school district. Home is currently updated and very livable if your plans are to build at a later date.* Bonus * to live hillside without hillside restrictions in the town of PV. Run don't walk to capture this needle in a hay stack.", "price": 8000, "address": "Street 2", "city": "Multan", "country": "Pakistan", "image": "https://3.bp.blogspot.com/-84l-BoUL090/VTDHcQzSTNI/AAAAAAAAuHI/Khftta_CF5E/s1920/wow-home-design.jpg", "facilities": { "bathrooms": "5", "parking": "1", "bedrooms": "4" }, "userEmail": "mukhtarhamza294@gmail.com", "createdAt": { "$date": "2023-04-14T10:42:19.231Z" }, "updatedAt": { "$date": "2023-04-14T10:42:19.231Z" } }, { "_id": { "$oid": "6439001c74446601d6fce96d" }, "title": "Citralan Puri Serang", "description": "Massive opportunity to build your dream home at the base of Mummy Mountain in the 3 C's school district. Home is currently updated and very livable if your plans are to build at a later date.* Bonus * to live hillside without hillside restrictions in the town of PV. Run don't walk to capture this needle in a hay stack.", "price": 3000, "address": "Street 3", "city": "California", "country": "US", "image": "https://images.pexels.com/photos/323780/pexels-photo-323780.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", "userEmail": "mukhtarhamza294@gmail.com", "createdAt": { "$date": "2023-04-14T07:26:20.051Z" }, "updatedAt": { "$date": "2023-04-14T07:26:20.051Z" }, "facilities": { "bathrooms": "3", "parking": "1", "bedrooms": "2" } } ]
添加的数组检查代码
<div className="paddings flexCenter properties"> { data && Array.isArray(data) ? ( data.map((card, i) => (<PropertyCard card={card} key={i} />)) ) : ( <p>No data available</p> ) } </div>
useProperties自定义Hook代码
import React from 'react' import { useQuery } from 'react-query' import { getAllProperties } from '../utils/api' const useProperties = () => { const { data, isLoading, isError, refetch } = useQuery( "allProperties", getAllProperties, { refetchOnWindowFocus: false } ) return ( data, isError, isLoading, refetch ) } export default useProperties
问题根源与修复方案
1. Hook返回值写法错误
useProperties的返回语句是逗号表达式,实际只会返回最后一个值refetch,导致组件中解构的data、isError、isLoading全是undefined,这才是报错的核心原因。
修复Hook的返回逻辑,改为返回对象:
const useProperties = () => { const { data, isLoading, isError, refetch } = useQuery( "allProperties", getAllProperties, { refetchOnWindowFocus: false } ) // 返回对象,确保组件能正确解构到对应属性 return { data, isError, isLoading, refetch } }
2. 数据兜底处理
即使修复了Hook,仍需给data设置兜底值,避免请求未完成或异常时出现undefined:
- 组件内兜底:
const { data = [], isError, isLoading } = useProperties()
- Hook内设置初始值:
const { data, isLoading, isError, refetch } = useQuery( "allProperties", getAllProperties, { refetchOnWindowFocus: false, initialData: [] // 初始状态设为空数组 } )
3. 验证API返回格式
确认getAllProperties是否正确解析了响应数据,如果API返回的是嵌套结构(比如{ data: [...] }),需要提取数组部分:
export const getAllProperties = async () => { const res = await fetch('/api/properties') const result = await res.json() // 确保返回的是数组 return result.data || result }
内容的提问来源于stack exchange,提问作者Kolyasik
相关产品推荐
相关产品推荐

