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

React集成Google Maps API报错:组件类型无效问题求助

React Google Maps 标记渲染错误解决方法

问题描述

用React开发网页,通过Google Maps API展示实时地图,给一组地理地址数组添加标记时,出现以下错误:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

错误栈:

Check the render method of `Map`.
    at createFiberFromTypeAndProps (http://localhost:3001/static/js/bundle.js:47804:21)
    at createFiberFromElement (http://localhost:3001/static/js/bundle.js:47825:19)
    at reconcileSingleElement (http://localhost:3001/static/js/bundle.js:36916:27)
    at reconcileChildFibers (http://localhost:3001/static/js/bundle.js:36966:39)
    at reconcileChildren (http://localhost:3001/static/js/bundle.js:39908:32)
    at mountIndeterminateComponent (http://localhost:3001/static/js/bundle.js:40745:9)
    at beginWork (http://localhost:3001/static/js/bundle.js:41973:20)
    at HTMLUnknownElement.callCallback (http://localhost:3001/static/js/bundle.js:26983:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3001/static/js/bundle.js:27027:20)
    at invokeGuardedCallback (http://localhost:3001/static/js/bundle.js:27084:35)

原代码

Map组件(loc.js)

import React, { useState, useEffect } from 'react';
import { MapContainer, Marker, GoogleApiWrapper } from 'google-maps-react';
import { Loader } from '@googlemaps/js-api-loader';

const Map = ({ google }) => {
    const [addresses, setAddresses] = useState([
        '1600 Amphitheatre Parkway, Mountain View, CA',
        '1 Infinite Loop, Cupertino, CA',
        '350 Fifth Avenue, New York, NY',
    ]);

    const [coordinates, setCoordinates] = useState([]);

    useEffect(() => {
        const loader = new Loader({
            apiKey: 'YOUR_API',
            version: 'weekly',
            libraries: ['places'],
        });

        loader.load().then(() => {
            const geocoder = new google.maps.Geocoder();

            const fetchCoordinates = async () => {
                const coordinates = [];

                for (let i = 0; i < addresses.length; i++) {
                    const result = await new Promise((resolve, reject) => {
                        geocoder.geocode({ address: addresses[i] }, (result, status) => {
                            if (status === 'OK') {
                                resolve(result[0].geometry.location);
                            } else {
                                reject(status);
                            }
                        });
                    });

                    coordinates.push(result);
                }

                setCoordinates(coordinates);
            };

            fetchCoordinates();
        });
    }, [addresses, google.maps.Geocoder, google.maps.places]);

    return (
        <MapContainer google={google} center={{ lat: 37.7749, lng: -122.4194 }} zoom={10}>
            {coordinates.map((coordinate, index) => (
                <Marker key={index} position={{ lat: coordinate.lat(), lng: coordinate.lng() }} />
            ))}
        </MapContainer>
    );
};

export default GoogleApiWrapper({
    apiKey: 'YOUR_API',
})(Map);

App.js

import { GoogleApiWrapper } from 'google-maps-react';
import Map from './components/locator/loc';

function App(props) {
    return (
        <div className="App">
            <Map google={props.google} />
        </div>
    );
}

export default GoogleApiWrapper({
    apiKey: 'YOUR_API',
})(App);

错误原因及修复方案

1. 组件名称混淆

google-maps-react库中没有MapContainer组件,正确的地图容器组件是Map,你混淆了它和其他Google Maps React库的组件名称。

2. 重复加载API

同时使用GoogleApiWrapper和@googlemaps/js-api-loader两种API加载方式,会导致重复初始化引发冲突,只需保留一种即可,推荐用google-maps-react的包装器。

3. 重复包装组件

App.js和Map组件都用GoogleApiWrapper包装,导致Google Maps API多次初始化,且传递google props时出现冲突,只需在一个组件上包装即可。

4. useEffect依赖项错误

google.maps.Geocoder和google.maps.places不适合作为依赖项,直接依赖传入的google props即可,它是稳定的引用。

修改后的代码

Map组件(loc.js)

import React, { useState, useEffect } from 'react';
import { Map, Marker, GoogleApiWrapper } from 'google-maps-react';

const MapComponent = ({ google }) => {
    const [addresses, setAddresses] = useState([
        '1600 Amphitheatre Parkway, Mountain View, CA',
        '1 Infinite Loop, Cupertino, CA',
        '350 Fifth Avenue, New York, NY',
    ]);

    const [coordinates, setCoordinates] = useState([]);

    useEffect(() => {
        if (!google) return;
        
        const geocoder = new google.maps.Geocoder();

        const fetchCoordinates = async () => {
            const coords = [];
            for (const addr of addresses) {
                try {
                    const result = await new Promise((resolve, reject) => {
                        geocoder.geocode({ address: addr }, (results, status) => {
                            if (status === google.maps.GeocoderStatus.OK) {
                                resolve(results[0].geometry.location);
                            } else {
                                reject(new Error(`地址解析失败 ${addr}: ${status}`));
                            }
                        });
                    });
                    coords.push(result);
                } catch (err) {
                    console.error(err);
                }
            }
            setCoordinates(coords);
        };

        fetchCoordinates();
    }, [addresses, google]);

    return (
        <Map 
            google={google} 
            center={{ lat: 37.7749, lng: -122.4194 }} 
            zoom={10}
            style={{ width: '100%', height: '80vh' }}
        >
            {coordinates.map((coord, index) => (
                <Marker 
                    key={index} 
                    position={{ lat: coord.lat(), lng: coord.lng() }} 
                />
            ))}
        </Map>
    );
};

export default GoogleApiWrapper({
    apiKey: 'YOUR_API',
    libraries: ['places'] // 在这里指定需要的地图库
})(MapComponent);

App.js

import Map from './components/locator/loc';

function App() {
    return (
        <div className="App">
            <Map />
        </div>
    );
}

export default App;

额外说明

  • 把原组件名Map改成MapComponent,避免和导入的Map组件重名,也可以直接修改导入名称。
  • 移除了@googlemaps/js-api-loader依赖,直接通过GoogleApiWrapper加载API并指定需要的places库。
  • 给Map组件添加基础样式,确保地图能正常显示。
  • 增加错误捕获,避免单个地址解析失败导致整个流程中断。

内容的提问来源于stack exchange,提问作者Taha Habib

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:24:53