Skip to content

Commit

Permalink
docs: shortened and reworked main readme
Browse files Browse the repository at this point in the history
  • Loading branch information
usefulthink committed Nov 1, 2023
1 parent 2fca77a commit d5088ac
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 161 deletions.
196 changes: 48 additions & 148 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,36 @@

[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/visgl/react-google-maps/tree/main/LICENSE)

A library to integrate the Google Maps JavaScript API into React Applications
using simple components or hooks.

The hooks provide the possibility to access different Google Maps Platform services and libraries, as well as the map instance
itself inside all components that are wrapped inside the `APIProvider`.
The map instance can only be accessed, if a `Map` component is used inside the `APIProvider`.

## Description

This is a Typescript / JavaScript library to integrate the Maps JavaScript API into your React application.
It comes with a collection of React components to create maps, markers and infowindows, and a set of
hooks to use some of the Maps JavaScript
API [Services](https://developers.google.com/maps/documentation/javascript#services)
and [Libraries](https://developers.google.com/maps/documentation/javascript/libraries).
This is a TypeScript / JavaScript library to integrate the Maps JavaScript API
into your React application.
It comes with a collection of React components to create maps, markers and
infowindows, and a set of hooks to use some of the Maps JavaScript API
[Services][gmp-services] and [Libraries][gmp-libraries].

## Installation

This library is available via npm as the package [@vis.gl/react-google-maps](https://www.npmjs.com/package/@vis.gl/react-google-maps).
This library is available on npm as [`@vis.gl/react-google-maps`][npm-package].

```sh
npm install --save @vis.gl/react-google-maps -D
npm install @vis.gl/react-google-maps
```

## Map Usage
## Usage

Import the `APIProvider` and wrap it around all components that should have access to the map instance(s).
All components that are children of the `APIProvider` can use hooks, components and access all map instance(s).
Import the [`APIProvider`][api-provider] and wrap it around all components that should have
access to the Google Maps API.
Any component within the context of the `APIProvider` can use the hooks and
components provided by this library.

Add a `Map` component inside the `APIProvider` to display a map on the screen. Inside the `Map` component, it is
possible to add components like a `Marker` or `InfoWindow` that can be displayed on the map. Also, all hooks can be used
inside all components.
To render a simple map, add a [`Map`][api-map] component inside the `APIProvider`.
Within the `Map` component, you can then add further components like
[`Marker`][api-marker], [`AdvancedMarker`][api-adv-marker], or
[`InfoWindow`][api-infowindow] to render content on the map.

For more advanced use-cases you can even add your own components to the map
that make use of `google.maps.OverlayView` or `google.maps.WebGlOverlayView`.

```tsx
import React from 'react';
import {APIProvider, Map, Marker} from '@vis.gl/react-google-maps';

function App() {
Expand All @@ -53,98 +49,20 @@ function App() {
export default App;
```

## Usage of the `useMap` hook

The `APIProvider` is used to load the Maps JavaScript API at the top level of the app component and provides a
context that holds all map instances that can be accessed via the `useMap` hook.

It is possible to use one or multiple `Map` components inside the `APIProvider`.
Make sure to pass the id of the map to the `useMap` hook when using multiple maps.

### Hook usage with one Map component

The `useMap()` hook can be used to directly access the `google.maps.Map` instance created by a `<Map>` component
in your application.

```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 = () => (
<APIProvider apiKey={'YOUR API KEY HERE'}>
<Map /* ... */></Map>

<MyComponent />
</APIProvider>
);
```

### Hook usage with multiple Map components

When multiple `Map` components are used, an additional prop `id` is required for all map components (internally, the
id `default` is used whenever no map-id is specified, which could lead to problems with multiple maps).

Inside the App component:

```tsx
import React from 'react';
import {APIProvider, Map} from '@vis.gl/react-google-maps';

function App() {
const position = {lat: 53.54992, lng: 10.00678};

return (
<APIProvider apiKey={'YOUR API KEY HERE'}>
<Map id={'map-1'} /* ... */ />
<Map id={'map-2'} /* ... */ />
</APIProvider>
);
}

export default App;
```

Inside another component, accessing the map instances:

```tsx
import React, {useEffect} from 'react';
import {useMap} from '@vis.gl/react-google-maps';

const MyComponent = () => {
const mapOne = useMap('map-1');
const mapTwo = useMap('map-2');

useEffect(() => {
if (!mapOne || !mapTwo) return;

// interact with the map-instances.
}, [mapOne, mapTwo]);
Please see our [documentation][docs] or [examples][] for more in-depth information
about this library.

return <></>;
};
```
### Using other libraries of the Maps JavaScript API

## Using other libraries of the Google Maps JavaScript API
Besides rendering maps, the Maps JavaScript API has a lot of
[additional libraries][gmp-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
the [`useMapsLibrary()`][api-use-lib] hook to handle dynamic loading of
additional libraries.

Besides rendering maps, 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:
For example, if you want to use the `google.maps.places.PlacesService` class in
your component, you can implement it like this:

```tsx
import {useMapsLibrary} from '@vis.gl/react-google-maps';
Expand All @@ -153,16 +71,14 @@ 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 placesLib = useMapsLibrary('places');
const [placesService, setPlacesService] = useState(null);

useEffect(() => {
if (!placesApiLoaded) return;
if (!placesLib) return;

// when placesApiLoaded is true, the library can be accessed via the
// global `google.maps` namespace.
setPlacesService(new google.maps.places.PlacesService());
}, [placesApiLoaded]);
setPlacesService(new placesLib.PlacesService());
}, [placesLib]);

useEffect(() => {
if (!placesService) return;
Expand All @@ -174,35 +90,19 @@ const MyComponent = () => {
};
```

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 <></>;
};
```

## Examples

Explore our [examples directory on GitHub](./examples) for full implementation examples.
Explore our [examples directory on GitHub](./examples) or the
[examples on our website][examples] for full implementation examples.

[api-provider]: https://visgl.github.io/react-google-maps/docs/api-reference/components/api-provider
[api-map]: https://visgl.github.io/react-google-maps/docs/api-reference/components/map
[api-marker]: https://visgl.github.io/react-google-maps/docs/api-reference/components/marker
[api-adv-marker]: https://visgl.github.io/react-google-maps/docs/api-reference/components/advanced-marker
[api-infowindow]: https://visgl.github.io/react-google-maps/docs/api-reference/components/info-window
[api-use-lib]: https://visgl.github.io/react-google-maps/docs/api-reference/hooks/useMapsLibrary
[docs]: https://visgl.github.io/react-google-maps/docs/
[examples]: https://visgl.github.io/react-google-maps/examples
[gmp-services]: https://developers.google.com/maps/documentation/javascript#services
[gmp-libraries]: https://developers.google.com/maps/documentation/javascript/libraries
[npm-package]: https://www.npmjs.com/package/@vis.gl/react-google-maps
49 changes: 39 additions & 10 deletions docs/api-reference/hooks/useMap.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# `useMap` Hook

React hook to get access to any [google.maps.Map][gmp-map-ref]
instance within the APIProvider.

[gmp-map-ref]: https://developers.google.com/maps/documentation/javascript/reference/map#Map
The `useMap()` hook can be used to directly access the
[`google.maps.Map`][gmp-map-ref] instance created by a
[`Map`](../components/map.md) component within the
[`APIProvider`](../components/api-provider.md) in your application.

## Usage

When there is only a single map within the `<APIProvider>`, the `useMap()` hook
can be called without any arguments and the `<Map>` doesn't need an id.
When there is only a single map within the `APIProvider`, the `useMap()`
hook can be called without any arguments and the `Map` doesn't need an id.

The same is true for components that are added as a child to the `Map`
component.

```tsx
const MyComponent = () => {
Expand All @@ -33,9 +36,9 @@ const App = () => {
};
```

If there are multiple `<Map>` components in the APIProvider, they are only retrievable
When there are multiple `Map` components in the `APIProvider`, they are only retrievable
using the `useMap()` hook when the hook is either called from a child-component of
the map or when an explicit id is specified on both the map and as a parameter of
a `Map` or when an explicit id is specified on both the map and as a parameter of
the `useMap()` hook.

```tsx
Expand Down Expand Up @@ -63,6 +66,32 @@ const App = () => {
};
```

## Return value
## Signature

`useMap(id?: string): google.maps.Map | null`

Returns the `google.maps.Map` instance or null if it can't be found

The returned map instance is determined as follows:

- If an `id` is specified, the map with that `id` is retrieved from the
`APIProviderContext`.
If that can't be found, return `null`.
- When no `id` is specified
- If there is a parent map instance, return it
- Otherwise, return the map with id `default` (maps without the `id` prop
are registered with id `default`).

Returns a [google.maps.Map](https://developers.google.com/maps/documentation/javascript/reference/map#Map).
### Parameters

#### `id`: string (optional)

The id of the map-instance to be returned. If not specified it will return
the parent map instance, or the default map instance if there is no parent.

## Source

[`src/hooks/use-map.tsx`][src]

[src]: https://github.com/visgl/react-google-maps/blob/main/src/hooks/use-map.tsx
[gmp-map-ref]: https://developers.google.com/maps/documentation/javascript/reference/map#Map
4 changes: 2 additions & 2 deletions docs/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Once that is set up, run `npm install` followed by `npm start` to start the deve
The library can be installed from npm:

```bash
npm install --save @vis.gl/react-google-maps
npm install @vis.gl/react-google-maps
```

This module comes with full TypeScript-support out of the box, so no additional module is
Expand All @@ -33,7 +33,7 @@ required for the typings.

A minimal example to just render a map looks like this:

```tsx
```tsx title=index.jsx
import React from 'react';
import {createRoot} from 'react-dom/client';
import {APIProvider, Map} from '@vis.gl/react-google-maps';
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/use-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const useMap = (id: string | null = null): google.maps.Map | null => {
const {mapInstances = {}} = useContext(APIProviderContext) || {};
const {map} = useContext(GoogleMapsContext) || {};

// if an if is specified, the corresponding map or null is returned
// if an id is specified, the corresponding map or null is returned
if (id !== null) return mapInstances[id] || null;

// otherwise, return the closest ancestor
Expand Down

0 comments on commit d5088ac

Please sign in to comment.