0
# Core Map Component
1
2
The main GoogleMap component that renders the interactive map container and manages the Google Maps instance, along with the useGoogleMap hook for accessing the map instance from child components.
3
4
## Capabilities
5
6
### GoogleMap Component
7
8
The primary component for rendering Google Maps with comprehensive configuration options and event handling.
9
10
```typescript { .api }
11
/**
12
* Main map container component that renders the Google Map
13
* All other map components must be rendered as children of GoogleMap
14
*/
15
interface GoogleMapProps {
16
children?: React.ReactNode;
17
id?: string;
18
mapContainerStyle?: React.CSSProperties;
19
mapContainerClassName?: string;
20
options?: google.maps.MapOptions;
21
extraMapTypes?: google.maps.MapType[];
22
23
// Map configuration
24
center?: google.maps.LatLng | google.maps.LatLngLiteral;
25
clickableIcons?: boolean;
26
heading?: number;
27
mapTypeId?: string;
28
streetView?: google.maps.StreetViewPanorama;
29
tilt?: number;
30
zoom?: number;
31
32
// Mouse events
33
onClick?: (e: google.maps.MapMouseEvent) => void;
34
onDblClick?: (e: google.maps.MapMouseEvent) => void;
35
onDrag?: () => void;
36
onDragEnd?: () => void;
37
onDragStart?: () => void;
38
onMouseMove?: (e: google.maps.MapMouseEvent) => void;
39
onMouseOut?: (e: google.maps.MapMouseEvent) => void;
40
onMouseOver?: (e: google.maps.MapMouseEvent) => void;
41
onMouseDown?: (e: google.maps.MapMouseEvent) => void;
42
onMouseUp?: (e: google.maps.MapMouseEvent) => void;
43
onRightClick?: (e: google.maps.MapMouseEvent) => void;
44
45
// Map state change events
46
onMapTypeIdChanged?: () => void;
47
onTilesLoaded?: () => void;
48
onBoundsChanged?: () => void;
49
onCenterChanged?: () => void;
50
onHeadingChanged?: () => void;
51
onIdle?: () => void;
52
onProjectionChanged?: () => void;
53
onResize?: () => void;
54
onTiltChanged?: () => void;
55
onZoomChanged?: () => void;
56
57
// Lifecycle events
58
onLoad?: (map: google.maps.Map) => void | Promise<void>;
59
onUnmount?: (map: google.maps.Map) => void | Promise<void>;
60
}
61
62
function GoogleMap(props: GoogleMapProps): JSX.Element;
63
```
64
65
**Usage Examples:**
66
67
```typescript
68
import React, { useCallback, useState } from 'react';
69
import { GoogleMap, LoadScript } from '@react-google-maps/api';
70
71
const mapContainerStyle = {
72
width: '100%',
73
height: '400px'
74
};
75
76
const center = {
77
lat: 40.7128,
78
lng: -74.0060
79
};
80
81
// Basic map
82
function BasicMap() {
83
return (
84
<LoadScript googleMapsApiKey="YOUR_API_KEY">
85
<GoogleMap
86
mapContainerStyle={mapContainerStyle}
87
center={center}
88
zoom={10}
89
/>
90
</LoadScript>
91
);
92
}
93
94
// Interactive map with events
95
function InteractiveMap() {
96
const [mapCenter, setMapCenter] = useState(center);
97
const [mapZoom, setMapZoom] = useState(10);
98
99
const onLoad = useCallback((map: google.maps.Map) => {
100
console.log('Map loaded:', map);
101
}, []);
102
103
const onClick = useCallback((e: google.maps.MapMouseEvent) => {
104
if (e.latLng) {
105
console.log('Clicked at:', e.latLng.toJSON());
106
setMapCenter(e.latLng.toJSON());
107
}
108
}, []);
109
110
const onCenterChanged = useCallback(() => {
111
console.log('Map center changed');
112
}, []);
113
114
return (
115
<LoadScript googleMapsApiKey="YOUR_API_KEY">
116
<GoogleMap
117
mapContainerStyle={mapContainerStyle}
118
center={mapCenter}
119
zoom={mapZoom}
120
options={{
121
disableDefaultUI: false,
122
clickableIcons: true,
123
scrollwheel: true,
124
}}
125
onClick={onClick}
126
onLoad={onLoad}
127
onCenterChanged={onCenterChanged}
128
onZoomChanged={() => console.log('Zoom changed')}
129
/>
130
</LoadScript>
131
);
132
}
133
134
// Map with custom styling and options
135
function StyledMap() {
136
const mapOptions: google.maps.MapOptions = {
137
disableDefaultUI: true,
138
clickableIcons: false,
139
scrollwheel: false,
140
disableDoubleClickZoom: true,
141
mapTypeControl: true,
142
mapTypeControlOptions: {
143
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
144
position: google.maps.ControlPosition.TOP_CENTER,
145
},
146
zoomControl: true,
147
zoomControlOptions: {
148
position: google.maps.ControlPosition.RIGHT_CENTER,
149
},
150
scaleControl: true,
151
streetViewControl: true,
152
streetViewControlOptions: {
153
position: google.maps.ControlPosition.LEFT_TOP,
154
},
155
fullscreenControl: false,
156
styles: [
157
{
158
featureType: "all",
159
elementType: "geometry",
160
stylers: [{ color: "#242f3e" }]
161
},
162
{
163
featureType: "all",
164
elementType: "labels.text.stroke",
165
stylers: [{ color: "#242f3e" }]
166
},
167
{
168
featureType: "all",
169
elementType: "labels.text.fill",
170
stylers: [{ color: "#746855" }]
171
}
172
]
173
};
174
175
return (
176
<LoadScript googleMapsApiKey="YOUR_API_KEY">
177
<GoogleMap
178
id="styled-map"
179
mapContainerStyle={mapContainerStyle}
180
mapContainerClassName="custom-map"
181
center={center}
182
zoom={10}
183
options={mapOptions}
184
/>
185
</LoadScript>
186
);
187
}
188
```
189
190
### Implementation Notes
191
192
GoogleMap is implemented as a class component with an internal functional variant (`GoogleMapF`) that uses React hooks. However, `GoogleMapF` is not exported from the main package and is not available for direct use. The main `GoogleMap` component should be used in all cases.
193
194
### useGoogleMap Hook
195
196
React hook that provides access to the current Google Map instance from the React Context within child components.
197
198
```typescript { .api }
199
/**
200
* Hook to access current Google Map instance from context
201
* Must be used within a GoogleMap component tree
202
* @returns The Google Maps instance or null if not available
203
*/
204
function useGoogleMap(): google.maps.Map | null;
205
```
206
207
**Usage Examples:**
208
209
```typescript
210
import React, { useEffect } from 'react';
211
import { GoogleMap, LoadScript, useGoogleMap } from '@react-google-maps/api';
212
213
// Custom component that accesses the map instance
214
function MapControls() {
215
const map = useGoogleMap();
216
217
useEffect(() => {
218
if (map) {
219
// Access map instance directly
220
console.log('Current map bounds:', map.getBounds());
221
console.log('Current zoom level:', map.getZoom());
222
223
// Add custom controls or modify map programmatically
224
const controlDiv = document.createElement('div');
225
controlDiv.innerHTML = '<button>Custom Control</button>';
226
map.controls[google.maps.ControlPosition.TOP_CENTER].push(controlDiv);
227
}
228
}, [map]);
229
230
const centerMap = () => {
231
if (map) {
232
map.setCenter({ lat: 40.7128, lng: -74.0060 });
233
map.setZoom(12);
234
}
235
};
236
237
return (
238
<div style={{ position: 'absolute', top: 10, left: 10, zIndex: 1 }}>
239
<button onClick={centerMap}>Center on NYC</button>
240
</div>
241
);
242
}
243
244
// Custom marker component that uses map instance
245
function CustomMapComponent() {
246
const map = useGoogleMap();
247
248
useEffect(() => {
249
if (map) {
250
// Create custom marker using native Google Maps API
251
const marker = new google.maps.Marker({
252
position: { lat: 40.7128, lng: -74.0060 },
253
map: map,
254
title: 'Custom Marker'
255
});
256
257
// Cleanup on unmount
258
return () => {
259
marker.setMap(null);
260
};
261
}
262
}, [map]);
263
264
return null; // This component doesn't render anything
265
}
266
267
// Usage within GoogleMap
268
function AppWithMapAccess() {
269
return (
270
<LoadScript googleMapsApiKey="YOUR_API_KEY">
271
<div style={{ position: 'relative' }}>
272
<GoogleMap
273
mapContainerStyle={{ width: '100%', height: '400px' }}
274
center={{ lat: 40.7128, lng: -74.0060 }}
275
zoom={10}
276
>
277
<MapControls />
278
<CustomMapComponent />
279
</GoogleMap>
280
</div>
281
</LoadScript>
282
);
283
}
284
```
285
286
### MapContext
287
288
React Context that provides the Google Map instance to child components.
289
290
```typescript { .api }
291
/**
292
* React Context for sharing Google Map instance
293
* Used internally by useGoogleMap hook
294
*/
295
interface MapContextValue {
296
map: google.maps.Map | null;
297
}
298
299
const MapContext: React.Context<MapContextValue>;
300
```
301
302
**Usage Examples:**
303
304
```typescript
305
import React, { useContext } from 'react';
306
import { MapContext } from '@react-google-maps/api';
307
308
// Direct context usage (useGoogleMap hook is preferred)
309
function DirectContextUsage() {
310
const { map } = useContext(MapContext);
311
312
React.useEffect(() => {
313
if (map) {
314
console.log('Map instance from context:', map);
315
}
316
}, [map]);
317
318
return null;
319
}
320
```
321
322
### Advanced Map Configuration
323
324
Advanced configuration patterns and map manipulation techniques.
325
326
```typescript { .api }
327
/**
328
* Advanced map configuration options
329
*/
330
interface AdvancedMapOptions extends google.maps.MapOptions {
331
// Restrict map bounds
332
restriction?: {
333
latLngBounds: google.maps.LatLngBounds;
334
strictBounds?: boolean;
335
};
336
337
// Custom map types
338
mapTypeControlOptions?: {
339
mapTypeIds?: (google.maps.MapTypeId | string)[];
340
style?: google.maps.MapTypeControlStyle;
341
position?: google.maps.ControlPosition;
342
};
343
}
344
```
345
346
**Advanced Usage Examples:**
347
348
```typescript
349
// Map with restricted bounds (e.g., for a specific region)
350
function RestrictedMap() {
351
const bounds = new google.maps.LatLngBounds(
352
new google.maps.LatLng(40.4774, -74.2591), // SW corner
353
new google.maps.LatLng(40.9176, -73.7004) // NE corner
354
);
355
356
const restrictedMapOptions: google.maps.MapOptions = {
357
restriction: {
358
latLngBounds: bounds,
359
strictBounds: false
360
},
361
center: { lat: 40.7128, lng: -74.0060 },
362
zoom: 10
363
};
364
365
return (
366
<GoogleMap
367
mapContainerStyle={{ width: '100%', height: '400px' }}
368
options={restrictedMapOptions}
369
/>
370
);
371
}
372
373
// Map with custom map type
374
function CustomMapTypeExample() {
375
const onLoad = useCallback((map: google.maps.Map) => {
376
// Add custom map type
377
const customMapType = new google.maps.ImageMapType({
378
getTileUrl: function(coord, zoom) {
379
return `https://example.com/tiles/${zoom}/${coord.x}/${coord.y}.png`;
380
},
381
tileSize: new google.maps.Size(256, 256),
382
maxZoom: 18,
383
minZoom: 0,
384
name: 'Custom'
385
});
386
387
map.mapTypes.set('custom', customMapType);
388
}, []);
389
390
const mapOptions: google.maps.MapOptions = {
391
mapTypeControlOptions: {
392
mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain', 'custom'],
393
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
394
position: google.maps.ControlPosition.TOP_CENTER
395
}
396
};
397
398
return (
399
<GoogleMap
400
mapContainerStyle={{ width: '100%', height: '400px' }}
401
center={{ lat: 40.7128, lng: -74.0060 }}
402
zoom={10}
403
options={mapOptions}
404
onLoad={onLoad}
405
/>
406
);
407
}
408
```