From 9ceea9b0ca5e573a1908650fd87aa8b07e3f091a Mon Sep 17 00:00:00 2001 From: Malte Modrow Date: Thu, 26 Oct 2023 16:20:39 +0200 Subject: [PATCH 1/3] docs: page about how to interact with the GM API --- docs/interacting-with-the-google-maps-api.md | 145 +++++++++++++++++++ docs/table-of-contents.json | 1 + 2 files changed, 146 insertions(+) create mode 100644 docs/interacting-with-the-google-maps-api.md diff --git a/docs/interacting-with-the-google-maps-api.md b/docs/interacting-with-the-google-maps-api.md new file mode 100644 index 00000000..9e290f42 --- /dev/null +++ b/docs/interacting-with-the-google-maps-api.md @@ -0,0 +1,145 @@ +# Interacting with the Google Maps API + +With the provided components you are able to declaratively create a [Google Map](./api-reference/components/map.md) or a map with [markers](./api-reference/components/marker.md) for example. + +Besides that there are three main ways and concepts to interact with the Google Maps API on lower level with this library. You can use the provided `hooks`, the `refs` that are available for some components or use the [useMapsLibrary](./api-reference/hooks/useMapsLibrary.md) hook to tap into other libraries and services of the Google Maps API or craft your own custom hooks. + +## Hooks + +There are several hooks that provide additional functionality for the map or maps you create. The main one being the [`useMap`](./api-reference/hooks/useMap.md) hook. This hooks give you access to the underlying `google.maps.Map` instance. Every child component that is wrapped in the `...` component has access to the map instance via this hook. + +```tsx +import React, {useEffect} from 'react'; +import {APIProvider, useMap} from '@vis.gl/react-google-maps'; + +const MyComponent = () => { + const map = useMap(); + + useEffect(() => { + if (!map) return; + + // here you can interact with the imperative maps API + }, [map]); + + return <>; +}; + +const App = () => ( + + + + + +); +``` + +Other hooks provide access to different Google Maps API services: + +- [useDirectionsService](./api-reference/hooks/useDirectionsService.md) for the [Directions Service](https://developers.google.com/maps/documentation/javascript/directions) +- [useStreetViewPanorama](./api-reference/hooks/useStreetViewPanorama.md) for the [Streetview Service](https://developers.google.com/maps/documentation/javascript/streetview) +- [useAutocomplete](./api-reference/hooks/useAutocomplete.md) for the [Places Widget](https://developers.google.com/maps/documentation/javascript/reference/places-widget) + +The [useMapsLibrary](./api-reference/hooks/useMapsLibrary.md) hook can be utilized to load other parts of the Google Maps API that are not loaded by default. For example the Places Service or the Geocoding Service. [Learn how to use this hook](#other-google-maps-api-libraries-and-services) + +## Refs + +The `` and the `` components accept a `ref` prop which provides access to the underlying `google.maps.Marker`/`google.maps.marker.AdvancedMarkerElement` instance. Here is an example of how to use the `useMarkerRef` hook to get access to a marker instance. The same concept applies for the `` (using the `useAdvancedMarkerRef` hook) + +```tsx +import React from 'react'; +import { + APIProvider, + Map, + Marker, + useMarkerRef +} from '@vis.gl/react-google-maps'; + +const App = () => { + const [markerRef, marker] = useMarkerRef(); + + useEffect(() => { + if (!marker) { + return; + } + + // do something with marker instance here + }, [marker]); + + return ( + + + + + + ); +}; + +export default App; +``` + +## Other Google Maps API libraries and services + +The Maps JavaScript API has a lot of [additional libraries](https://developers.google.com/maps/documentation/javascript/libraries) +for things like geocoding, routing, the Places API, Street View, and a lot more. These libraries +are not loaded by default, which is why this module provides a hook +`useMapsLibrary()` to handle dynamic loading of those libraries. + +For example, if you want to write a component that needs to use the +`google.maps.places.PlacesService` class, you can implement it like this: + +```tsx +import {useMapsLibrary} from '@vis.gl/react-google-maps'; + +const MyComponent = () => { + // triggers loading the places library and returns true once complete (the + // component calling the hook gets automatically re-rendered when this is + // the case) + const placesApiLoaded = useMapsLibrary('places'); + const [placesService, setPlacesService] = useState(null); + + useEffect(() => { + if (!placesApiLoaded) return; + + // when placesApiLoaded is true, the library can be accessed via the + // global `google.maps` namespace. + setPlacesService(new google.maps.places.PlacesService()); + }, [placesApiLoaded]); + + useEffect(() => { + if (!placesService) return; + + // ...use placesService... + }, [placesService]); + + return <>; +}; +``` + +Or you can extract your own hook from this: + +```tsx +function usePlacesService() { + const placesApiLoaded = useMapsLibrary('places'); + const [placesService, setPlacesService] = useState(null); + + useEffect(() => { + if (!placesApiLoaded) return; + + setPlacesService(new google.maps.places.PlacesService()); + }, [placesApiLoaded]); + + return placesService; +} + +const MyComponent = () => { + const placesService = usePlacesService(); + + useEffect(() => { + if (!placesService) return; + + // ... use placesService ... + }, [placesService]); + + return <>; +}; +``` diff --git a/docs/table-of-contents.json b/docs/table-of-contents.json index 376f051c..58876c34 100644 --- a/docs/table-of-contents.json +++ b/docs/table-of-contents.json @@ -5,6 +5,7 @@ "items": [ "README", "get-started", + "interacting-with-the-google-maps-api", "whats-new", "upgrade-guide", "contributing" From 80e7c95de71096e98ed789a444e15b1aa177b053 Mon Sep 17 00:00:00 2001 From: Malte Modrow Date: Thu, 26 Oct 2023 17:12:12 +0200 Subject: [PATCH 2/3] docs: use new implementation of useMapsLibrary --- docs/interacting-with-the-google-maps-api.md | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/interacting-with-the-google-maps-api.md b/docs/interacting-with-the-google-maps-api.md index 9e290f42..52903338 100644 --- a/docs/interacting-with-the-google-maps-api.md +++ b/docs/interacting-with-the-google-maps-api.md @@ -91,19 +91,20 @@ For example, if you want to write a component that needs to use the import {useMapsLibrary} from '@vis.gl/react-google-maps'; const MyComponent = () => { - // triggers loading the places library and returns true once complete (the + // triggers loading the places library and returns the API Object once complete (the // component calling the hook gets automatically re-rendered when this is // the case) - const placesApiLoaded = useMapsLibrary('places'); + const placesLibrary = useMapsLibrary('places'); + const [placesService, setPlacesService] = useState(null); useEffect(() => { - if (!placesApiLoaded) return; + if (!placesLibrary) return; - // when placesApiLoaded is true, the library can be accessed via the - // global `google.maps` namespace. - setPlacesService(new google.maps.places.PlacesService()); - }, [placesApiLoaded]); + // when placesLibrary is loaded, the library can be accessed via the + // placesLibrary API object + setPlacesService(new placesLibrary.PlacesService()); + }, [placesLibrary]); useEffect(() => { if (!placesService) return; @@ -119,14 +120,14 @@ Or you can extract your own hook from this: ```tsx function usePlacesService() { - const placesApiLoaded = useMapsLibrary('places'); + const placesLibrary = useMapsLibrary('places'); const [placesService, setPlacesService] = useState(null); useEffect(() => { - if (!placesApiLoaded) return; + if (!placesLibrary) return; - setPlacesService(new google.maps.places.PlacesService()); - }, [placesApiLoaded]); + setPlacesService(new placesLibrary.PlacesService()); + }, [placesLibrary]); return placesService; } From 19141296969c076094ceb4a5c37e1546e5b7a94a Mon Sep 17 00:00:00 2001 From: Martin Schuhfuss Date: Wed, 1 Nov 2023 15:05:49 +0100 Subject: [PATCH 3/3] Update docs/interacting-with-the-google-maps-api.md --- docs/interacting-with-the-google-maps-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/interacting-with-the-google-maps-api.md b/docs/interacting-with-the-google-maps-api.md index 52903338..07d61a8e 100644 --- a/docs/interacting-with-the-google-maps-api.md +++ b/docs/interacting-with-the-google-maps-api.md @@ -2,7 +2,7 @@ With the provided components you are able to declaratively create a [Google Map](./api-reference/components/map.md) or a map with [markers](./api-reference/components/marker.md) for example. -Besides that there are three main ways and concepts to interact with the Google Maps API on lower level with this library. You can use the provided `hooks`, the `refs` that are available for some components or use the [useMapsLibrary](./api-reference/hooks/useMapsLibrary.md) hook to tap into other libraries and services of the Google Maps API or craft your own custom hooks. +Besides that there are three main ways and concepts to interact with the Google Maps API on lower level with this library. You can use the provided hooks, the refs that are available for some components or use the [`useMapsLibrary`](./api-reference/hooks/useMapsLibrary.md) hook to tap into other libraries and services of the Google Maps API or craft your own custom hooks. ## Hooks