You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:36:26