React.js Google Maps API integration with components and hooks for seamless Google Maps functionality
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Layer components for displaying additional information overlays on the map including traffic data, transit routes, bicycling paths, heatmaps, and KML/KMZ files.
Displays real-time traffic information on the map with customizable styling and update intervals.
/**
* Displays traffic information on the map
* Shows real-time traffic conditions with color-coded congestion levels
*/
interface TrafficLayerProps {
options?: google.maps.TrafficLayerOptions;
// Lifecycle events
onLoad?: (trafficLayer: google.maps.TrafficLayer) => void;
onUnmount?: (trafficLayer: google.maps.TrafficLayer) => void;
}
function TrafficLayer(props: TrafficLayerProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import { GoogleMap, LoadScript, TrafficLayer } from '@react-google-maps/api';
// Basic traffic layer
function BasicTrafficLayer() {
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<TrafficLayer />
</GoogleMap>
</LoadScript>
);
}
// Toggle traffic layer
function ToggleableTrafficLayer() {
const [showTraffic, setShowTraffic] = useState(true);
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<div>
<div style={{ padding: '10px' }}>
<button onClick={() => setShowTraffic(!showTraffic)}>
{showTraffic ? 'Hide' : 'Show'} Traffic
</button>
</div>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{showTraffic && (
<TrafficLayer
onLoad={() => console.log('Traffic layer loaded')}
/>
)}
</GoogleMap>
</div>
</LoadScript>
);
}
// Traffic layer with custom options
function CustomTrafficLayer() {
const trafficOptions = {
autoRefresh: true,
// Additional traffic layer options can be configured here
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<TrafficLayer
options={trafficOptions}
onLoad={(trafficLayer) => {
console.log('Traffic layer loaded with options:', trafficOptions);
}}
/>
</GoogleMap>
</LoadScript>
);
}Functional component variant of TrafficLayer that uses React hooks internally.
/**
* Functional variant of TrafficLayer component using hooks internally
*/
function TrafficLayerF(props: TrafficLayerProps): JSX.Element;Displays bicycling routes and bike-friendly paths on the map.
/**
* Displays bicycling routes and paths on the map
* Shows bike lanes, bike paths, and bike-friendly routes
*/
interface BicyclingLayerProps {
// Lifecycle events
onLoad?: (bicyclingLayer: google.maps.BicyclingLayer) => void;
onUnmount?: (bicyclingLayer: google.maps.BicyclingLayer) => void;
}
function BicyclingLayer(props: BicyclingLayerProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import { GoogleMap, LoadScript, BicyclingLayer } from '@react-google-maps/api';
// Basic bicycling layer
function BasicBicyclingLayer() {
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={14}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<BicyclingLayer />
</GoogleMap>
</LoadScript>
);
}
// Combined layers example
function CombinedTransportationLayers() {
const [activeLayers, setActiveLayers] = useState({
bicycling: true,
traffic: false
});
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<div>
<div style={{ padding: '10px' }}>
<label>
<input
type="checkbox"
checked={activeLayers.bicycling}
onChange={(e) => setActiveLayers(prev => ({
...prev,
bicycling: e.target.checked
}))}
/>
Bicycling Routes
</label>
<label style={{ marginLeft: '20px' }}>
<input
type="checkbox"
checked={activeLayers.traffic}
onChange={(e) => setActiveLayers(prev => ({
...prev,
traffic: e.target.checked
}))}
/>
Traffic
</label>
</div>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={14}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{activeLayers.bicycling && (
<BicyclingLayer
onLoad={() => console.log('Bicycling layer loaded')}
/>
)}
{activeLayers.traffic && (
<TrafficLayer
onLoad={() => console.log('Traffic layer loaded')}
/>
)}
</GoogleMap>
</div>
</LoadScript>
);
}Functional component variant of BicyclingLayer that uses React hooks internally.
/**
* Functional variant of BicyclingLayer component using hooks internally
*/
function BicyclingLayerF(props: BicyclingLayerProps): JSX.Element;Displays public transit information including bus routes, subway lines, and transit stops.
/**
* Displays public transit information on the map
* Shows bus routes, subway lines, and transit stops
*/
interface TransitLayerProps {
// Lifecycle events
onLoad?: (transitLayer: google.maps.TransitLayer) => void;
onUnmount?: (transitLayer: google.maps.TransitLayer) => void;
}
function TransitLayer(props: TransitLayerProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import {
GoogleMap,
LoadScript,
TransitLayer,
TrafficLayer,
BicyclingLayer
} from '@react-google-maps/api';
// Basic transit layer
function BasicTransitLayer() {
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<TransitLayer />
</GoogleMap>
</LoadScript>
);
}
// Multi-modal transportation layers
function MultiModalTransport() {
const [layers, setLayers] = useState({
transit: true,
traffic: false,
bicycling: false
});
const toggleLayer = (layerName: string) => {
setLayers(prev => ({
...prev,
[layerName]: !prev[layerName as keyof typeof prev]
}));
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<div>
<div style={{
padding: '10px',
background: '#f5f5f5',
borderBottom: '1px solid #ddd'
}}>
<h4 style={{ margin: '0 0 10px 0' }}>Transportation Layers</h4>
<button
onClick={() => toggleLayer('transit')}
style={{
marginRight: '10px',
padding: '5px 10px',
backgroundColor: layers.transit ? '#4285f4' : '#fff',
color: layers.transit ? 'white' : '#333',
border: '1px solid #4285f4',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Public Transit
</button>
<button
onClick={() => toggleLayer('traffic')}
style={{
marginRight: '10px',
padding: '5px 10px',
backgroundColor: layers.traffic ? '#ea4335' : '#fff',
color: layers.traffic ? 'white' : '#333',
border: '1px solid #ea4335',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Traffic
</button>
<button
onClick={() => toggleLayer('bicycling')}
style={{
padding: '5px 10px',
backgroundColor: layers.bicycling ? '#34a853' : '#fff',
color: layers.bicycling ? 'white' : '#333',
border: '1px solid #34a853',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Bicycling
</button>
</div>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{layers.transit && (
<TransitLayer
onLoad={() => console.log('Transit layer loaded')}
/>
)}
{layers.traffic && (
<TrafficLayer
onLoad={() => console.log('Traffic layer loaded')}
/>
)}
{layers.bicycling && (
<BicyclingLayer
onLoad={() => console.log('Bicycling layer loaded')}
/>
)}
</GoogleMap>
</div>
</LoadScript>
);
}Functional component variant of TransitLayer that uses React hooks internally.
/**
* Functional variant of TransitLayer component using hooks internally
*/
function TransitLayerF(props: TransitLayerProps): JSX.Element;Displays data as a heatmap overlay with customizable appearance and data weighting options.
/**
* Displays data as a heatmap overlay
* Shows density and intensity of data points using color gradients
*/
interface HeatmapLayerProps {
data: google.maps.LatLng[] | google.maps.visualization.WeightedLocation[];
options?: google.maps.visualization.HeatmapLayerOptions;
// Lifecycle events
onLoad?: (heatmapLayer: google.maps.visualization.HeatmapLayer) => void;
onUnmount?: (heatmapLayer: google.maps.visualization.HeatmapLayer) => void;
}
function HeatmapLayer(props: HeatmapLayerProps): JSX.Element;Usage Examples:
import React, { useState, useMemo } from 'react';
import { GoogleMap, LoadScript, HeatmapLayer } from '@react-google-maps/api';
// Basic heatmap with random data
function BasicHeatmap() {
const heatmapData = useMemo(() => {
const data = [];
const center = { lat: 40.7128, lng: -74.0060 };
// Generate random data points around NYC
for (let i = 0; i < 100; i++) {
data.push(new google.maps.LatLng(
center.lat + (Math.random() - 0.5) * 0.1,
center.lng + (Math.random() - 0.5) * 0.1
));
}
return data;
}, []);
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY" libraries={['visualization']}>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={12}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<HeatmapLayer data={heatmapData} />
</GoogleMap>
</LoadScript>
);
}
// Weighted heatmap with custom styling
function WeightedHeatmap() {
const [radius, setRadius] = useState(20);
const [opacity, setOpacity] = useState(0.6);
const weightedData = useMemo(() => {
const locations = [
{ location: new google.maps.LatLng(40.7128, -74.0060), weight: 10 },
{ location: new google.maps.LatLng(40.7589, -73.9851), weight: 5 },
{ location: new google.maps.LatLng(40.7505, -73.9934), weight: 8 },
{ location: new google.maps.LatLng(40.7614, -73.9776), weight: 3 },
{ location: new google.maps.LatLng(40.7489, -73.9680), weight: 7 }
];
// Add more random weighted points
for (let i = 0; i < 50; i++) {
locations.push({
location: new google.maps.LatLng(
40.7128 + (Math.random() - 0.5) * 0.08,
-74.0060 + (Math.random() - 0.5) * 0.08
),
weight: Math.random() * 5 + 1
});
}
return locations;
}, []);
const heatmapOptions = {
radius,
opacity,
gradient: [
'rgba(0, 255, 255, 0)',
'rgba(0, 255, 255, 1)',
'rgba(0, 191, 255, 1)',
'rgba(0, 127, 255, 1)',
'rgba(0, 63, 255, 1)',
'rgba(0, 0, 255, 1)',
'rgba(0, 0, 223, 1)',
'rgba(0, 0, 191, 1)',
'rgba(0, 0, 159, 1)',
'rgba(0, 0, 127, 1)',
'rgba(63, 0, 91, 1)',
'rgba(127, 0, 63, 1)',
'rgba(191, 0, 31, 1)',
'rgba(255, 0, 0, 1)'
]
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY" libraries={['visualization']}>
<div>
<div style={{ padding: '10px', background: '#f0f0f0' }}>
<div style={{ marginBottom: '10px' }}>
<label>
Radius: {radius}
<input
type="range"
min="10"
max="50"
value={radius}
onChange={(e) => setRadius(parseInt(e.target.value))}
style={{ marginLeft: '10px' }}
/>
</label>
</div>
<div>
<label>
Opacity: {opacity.toFixed(1)}
<input
type="range"
min="0.1"
max="1"
step="0.1"
value={opacity}
onChange={(e) => setOpacity(parseFloat(e.target.value))}
style={{ marginLeft: '10px' }}
/>
</label>
</div>
</div>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={12}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<HeatmapLayer
data={weightedData}
options={heatmapOptions}
onLoad={() => console.log('Heatmap loaded')}
/>
</GoogleMap>
</div>
</LoadScript>
);
}
// Dynamic heatmap with data updates
function DynamicHeatmap() {
const [dataPoints, setDataPoints] = useState<google.maps.visualization.WeightedLocation[]>([]);
const addDataPoint = (lat: number, lng: number) => {
const newPoint = {
location: new google.maps.LatLng(lat, lng),
weight: Math.random() * 10 + 1
};
setDataPoints(prev => [...prev, newPoint]);
};
const clearData = () => {
setDataPoints([]);
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY" libraries={['visualization']}>
<div>
<div style={{ padding: '10px', background: '#f0f0f0' }}>
<div>Data Points: {dataPoints.length}</div>
<button
onClick={() => addDataPoint(
40.7128 + (Math.random() - 0.5) * 0.05,
-74.0060 + (Math.random() - 0.5) * 0.05
)}
style={{ marginRight: '10px' }}
>
Add Random Point
</button>
<button onClick={clearData}>
Clear All
</button>
</div>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
onClick={(e) => {
if (e.latLng) {
addDataPoint(e.latLng.lat(), e.latLng.lng());
}
}}
>
{dataPoints.length > 0 && (
<HeatmapLayer
data={dataPoints}
options={{
radius: 25,
opacity: 0.7
}}
/>
)}
</GoogleMap>
</div>
</LoadScript>
);
}Functional component variant of HeatmapLayer that uses React hooks internally.
/**
* Functional variant of HeatmapLayer component using hooks internally
*/
function HeatmapLayerF(props: HeatmapLayerProps): JSX.Element;Displays KML and KMZ files on the map with support for custom styling and interaction events.
/**
* Displays KML and KMZ files on the map
* Supports remote file loading and custom styling options
*/
interface KmlLayerProps {
url: string;
options?: google.maps.KmlLayerOptions;
// Event handlers
onClick?: (e: google.maps.KmlMouseEvent) => void;
onDefaultViewportChanged?: () => void;
onStatusChanged?: () => void;
// Lifecycle events
onLoad?: (kmlLayer: google.maps.KmlLayer) => void;
onUnmount?: (kmlLayer: google.maps.KmlLayer) => void;
}
function KmlLayer(props: KmlLayerProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import { GoogleMap, LoadScript, KmlLayer } from '@react-google-maps/api';
// Basic KML layer
function BasicKmlLayer() {
const kmlUrl = 'https://developers.google.com/maps/documentation/javascript/examples/kml/westcampus.kml';
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 37.4419, lng: -122.1419 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<KmlLayer
url={kmlUrl}
onLoad={() => console.log('KML layer loaded')}
onClick={(e) => {
console.log('KML feature clicked:', e.featureData);
}}
/>
</GoogleMap>
</LoadScript>
);
}
// Multiple KML layers with controls
function MultipleKmlLayers() {
const [activeLayers, setActiveLayers] = useState({
layer1: true,
layer2: false,
layer3: false
});
const kmlLayers = [
{
id: 'layer1',
name: 'Campus Buildings',
url: 'https://developers.google.com/maps/documentation/javascript/examples/kml/westcampus.kml'
},
{
id: 'layer2',
name: 'Parking Areas',
url: 'https://example.com/parking.kml'
},
{
id: 'layer3',
name: 'Walking Paths',
url: 'https://example.com/paths.kml'
}
];
const toggleLayer = (layerId: string) => {
setActiveLayers(prev => ({
...prev,
[layerId]: !prev[layerId as keyof typeof prev]
}));
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<div>
<div style={{ padding: '10px', background: '#f0f0f0' }}>
<h4>KML Layers</h4>
{kmlLayers.map(layer => (
<div key={layer.id} style={{ marginBottom: '5px' }}>
<label>
<input
type="checkbox"
checked={activeLayers[layer.id as keyof typeof activeLayers]}
onChange={() => toggleLayer(layer.id)}
/>
{layer.name}
</label>
</div>
))}
</div>
<GoogleMap
center={{ lat: 37.4419, lng: -122.1419 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{kmlLayers.map(layer =>
activeLayers[layer.id as keyof typeof activeLayers] && (
<KmlLayer
key={layer.id}
url={layer.url}
options={{
suppressInfoWindows: false,
preserveViewport: true
}}
onLoad={() => console.log(`${layer.name} loaded`)}
onClick={(e) => console.log(`${layer.name} feature clicked:`, e)}
onStatusChanged={() => console.log(`${layer.name} status changed`)}
/>
)
)}
</GoogleMap>
</div>
</LoadScript>
);
}
// KML layer with error handling
function KmlLayerWithErrorHandling() {
const [kmlUrl, setKmlUrl] = useState('');
const [layerStatus, setLayerStatus] = useState('');
const [loadedLayer, setLoadedLayer] = useState<google.maps.KmlLayer | null>(null);
const loadKmlFile = () => {
if (!kmlUrl.trim()) {
alert('Please enter a KML URL');
return;
}
setLayerStatus('Loading...');
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<div>
<div style={{ padding: '10px', background: '#f0f0f0' }}>
<div style={{ marginBottom: '10px' }}>
<input
type="text"
placeholder="Enter KML URL"
value={kmlUrl}
onChange={(e) => setKmlUrl(e.target.value)}
style={{ width: '300px', marginRight: '10px' }}
/>
<button onClick={loadKmlFile}>Load KML</button>
</div>
{layerStatus && (
<div>Status: {layerStatus}</div>
)}
</div>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={10}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{kmlUrl && (
<KmlLayer
url={kmlUrl}
onLoad={(kmlLayer) => {
setLoadedLayer(kmlLayer);
setLayerStatus('Loaded successfully');
console.log('KML layer loaded:', kmlLayer.getUrl());
}}
onStatusChanged={() => {
if (loadedLayer) {
const status = loadedLayer.getStatus();
setLayerStatus(`Status: ${status}`);
if (status === google.maps.KmlLayerStatus.INVALID_DOCUMENT) {
setLayerStatus('Error: Invalid KML document');
} else if (status === google.maps.KmlLayerStatus.DOCUMENT_NOT_FOUND) {
setLayerStatus('Error: KML document not found');
} else if (status === google.maps.KmlLayerStatus.FETCH_ERROR) {
setLayerStatus('Error: Failed to fetch KML document');
}
}
}}
onClick={(e) => {
console.log('KML feature clicked:', {
featureData: e.featureData,
pixelOffset: e.pixelOffset
});
}}
/>
)}
</GoogleMap>
</div>
</LoadScript>
);
}Guidelines for effectively combining and managing multiple map layers.
/**
* Best practices for layer management
*/
interface LayerManagerProps {
children: React.ReactNode;
maxConcurrentLayers?: number;
onLayerLimitExceeded?: (layerCount: number) => void;
}
// Example layer management patterns
const LayerManager = ({ children, maxConcurrentLayers = 5 }: LayerManagerProps) => {
const [activeLayers, setActiveLayers] = React.useState<string[]>([]);
const addLayer = (layerId: string) => {
if (activeLayers.length >= maxConcurrentLayers) {
console.warn('Maximum layer limit reached');
return false;
}
setActiveLayers(prev => [...prev, layerId]);
return true;
};
const removeLayer = (layerId: string) => {
setActiveLayers(prev => prev.filter(id => id !== layerId));
};
return <>{children}</>;
};Layer Performance Examples:
// Optimized layer switching
function OptimizedLayerSwitching() {
const [activeTransportLayer, setActiveTransportLayer] = useState<'traffic' | 'transit' | 'bicycling' | null>('traffic');
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY" libraries={['visualization']}>
<div>
<div style={{ padding: '10px' }}>
<select
value={activeTransportLayer || ''}
onChange={(e) => setActiveTransportLayer(e.target.value as any || null)}
>
<option value="">No Transport Layer</option>
<option value="traffic">Traffic</option>
<option value="transit">Transit</option>
<option value="bicycling">Bicycling</option>
</select>
</div>
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{activeTransportLayer === 'traffic' && <TrafficLayer />}
{activeTransportLayer === 'transit' && <TransitLayer />}
{activeTransportLayer === 'bicycling' && <BicyclingLayer />}
</GoogleMap>
</div>
</LoadScript>
);
}Install with Tessl CLI
npx tessl i tessl/npm-react-google-maps--api