如何解决React中map()使用async导致的Promise子元素错误
解决React Google Map中async map导致的"Objects are not valid as a React child"错误
问题根源
你在data.map()中使用了async函数,这会让map返回一个Promise数组,而React无法直接渲染Promise对象,因此触发了Error: Objects are not valid as a React child (found: [object Promise])错误。
解决方案
核心思路是提前批量获取所有地址的经纬度,将结果存入组件状态,等数据就绪后再渲染Marker。具体步骤如下:
- 新增状态存储包含经纬度的地址数据
- 利用
useEffect在地图加载完成后,批量请求坐标 - 渲染时直接遍历已处理的状态数据生成Marker
修改后的完整代码
import React, { useState, useEffect } from 'react' import { GoogleMap, useLoadScript, MarkerF } from "@react-google-maps/api" import { data } from './data' const API_KEY = "A1B2C3D4E5F6G" // 实际项目中请用环境变量 export default function GoogleMapAPI() { const { isLoaded } = useLoadScript({ googleMapsApiKey: API_KEY, }) // 存储带经纬度的地址数据 const [locationsWithCoords, setLocationsWithCoords] = useState([]) // 单个地址解析函数,统一用async/await,增加错误处理 const getCoordinates = async (address) => { try { // 用encodeURIComponent处理地址中的特殊字符(如空格) const encodedAddress = encodeURIComponent(address) const response = await fetch( `https://maps.googleapis.com/maps/api/geocode/json?address=${encodedAddress}&key=${API_KEY}` ) const result = await response.json() if (result.results.length === 0) { console.warn(`地址解析失败:${address}`) return { lat: 0, lng: 0 } // 返回默认坐标或跳过 } const { lat, lng } = result.results[0].geometry.location return { lat, lng } } catch (error) { console.error(`请求地址坐标失败:${error}`) return { lat: 0, lng: 0 } } } // 批量获取所有地址的坐标 useEffect(() => { if (!isLoaded) return const fetchAllCoordinates = async () => { const coordsList = await Promise.all( data.map(async (item) => { const coords = await getCoordinates(item.address) return { ...item, coords } }) ) setLocationsWithCoords(coordsList) } fetchAllCoordinates() }, [isLoaded]) if (!isLoaded) return <div>Loading...</div> return ( <GoogleMap zoom={11} center={{ lat: 35.68545216217928, lng: 139.75273062972732 }} mapContainerClassName='my__class' > {/* 直接遍历已处理的状态数据渲染Marker */} {locationsWithCoords.map((item, index) => ( <MarkerF key={index} // 实际项目建议用唯一ID代替index position={item.coords} /> ))} </GoogleMap> ) }
额外优化点
- 用
encodeURIComponent处理地址,避免特殊字符导致请求失败 - 增加错误处理,防止单个地址解析失败影响整个地图渲染
- 使用
Promise.all批量请求,提升效率 - 给Marker添加唯一
key属性,符合React列表渲染规范
内容的提问来源于stack exchange,提问作者kawa
相关产品推荐
相关产品推荐

