React组件用Google Map API刷新报错:TypeError: Cannot read 'maps' of undefined
Hey Gloria, sorry to hear you're hitting this frustrating issue—first load works smoothly, but refresh breaks things. Let's break down the most likely causes and fixes to get your map running reliably every time.
Common Causes & Step-by-Step Fixes
1. Google Maps Script Isn't Ready When Your Component Initializes
The biggest culprit here is timing: when you refresh the page, your React component's componentDidMount fires before the Google Maps script finishes loading. That means window.google is undefined when you try to call initMap(), throwing an error. (First load works because the script is cached and loads faster.)
Fix: Dynamically Load the Script On Demand
Instead of relying on the script being loaded upfront, check if window.google exists first. If not, load the script dynamically and initialize the map only after it's fully loaded:
import React, { Component } from 'react'; import './index.css'; class App extends Component { componentDidMount() { // Check if Google Maps is already available if (!window.google?.maps) { this.loadGoogleMapsScript(); } else { this.initMap(); } } loadGoogleMapsScript() { const script = document.createElement('script'); // Replace with your actual Google Maps API key script.src = `https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY`; script.async = true; script.defer = true; // Initialize map once the script finishes loading script.onload = () => { this.initMap(); }; document.body.appendChild(script); } initMap() { const latLong = { lat: -25.363, lng: 131.044 }; const options = { zoom: 5, center: latLong }; // Ensure the map container exists before initializing const mapElement = document.getElementById('map'); if (mapElement) { new window.google.maps.Map(mapElement, options); } } render() { return <div id="map" className="map-container"></div>; } } export default App;
2. Leftover Map Instances Cause Conflicts
If your component unmounts and remounts (like on refresh), leftover map instances can create memory leaks or unexpected errors.
Fix: Clean Up the Map Instance On Unmount
Store the map instance as a class property and destroy it when the component unmounts:
class App extends Component { mapInstance = null; // ... (keep script loading and initMap logic from above) initMap() { const latLong = { lat: -25.363, lng: 131.044 }; const options = { zoom: 5, center: latLong }; const mapElement = document.getElementById('map'); if (mapElement) { this.mapInstance = new window.google.maps.Map(mapElement, options); } } componentWillUnmount() { // Clean up to avoid memory leaks and conflicts if (this.mapInstance) { this.mapInstance = null; } } // ... }
3. DOM Element Isn't Ready When Initializing the Map
Sometimes on refresh, document.getElementById('map') returns null because the component's DOM hasn't fully rendered yet when initMap() runs.
Fix: Use React Refs for Reliable DOM Access
Replace getElementById with a React ref to ensure you're accessing the map container only after it's rendered:
class App extends Component { mapRef = React.createRef(); mapInstance = null; componentDidMount() { if (!window.google?.maps) { this.loadGoogleMapsScript(); } else { this.initMap(); } } loadGoogleMapsScript() { const script = document.createElement('script'); script.src = `https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY`; script.async = true; script.defer = true; script.onload = () => { this.initMap(); }; document.body.appendChild(script); } initMap() { const latLong = { lat: -25.363, lng: 131.044 }; const options = { zoom: 5, center: latLong }; // Use the ref to access the DOM element safely if (this.mapRef.current) { this.mapInstance = new window.google.maps.Map(this.mapRef.current, options); } } componentWillUnmount() { if (this.mapInstance) { this.mapInstance = null; } } render() { return <div ref={this.mapRef} className="map-container"></div>; } } export default App;
Quick Pre-Flight Checks
- Double-check your Google Maps API key is valid and has the Maps JavaScript API enabled in the Google Cloud Console.
- Ensure your
.map-containerCSS has a defined height (maps won't render if the container has 0 height).
Start with the dynamic script loading fix—it's the most common cause of this refresh issue. Let me know if you hit any snags!
内容的提问来源于stack exchange,提问作者Gloria Wu

