fullstackreact / google-maps-react

Companion code to the "How to Write a Google Maps React Component" Tutorial
https://www.fullstackreact.com/articles/how-to-write-a-google-maps-react-component/
MIT License
1.64k stars 818 forks source link

Is there a pan animation? #349

Open danksky opened 5 years ago

danksky commented 5 years ago

I know that Google Maps has a panTo() function in their javascript API. I was wondering how that can be called in a react-ful way using this component/wrapper?

cilliemalan commented 5 years ago

The key technicality is getting to the Google maps object, on which you can call the panTo method. One way to achieve this is to "capture" it once onLoad fires:

const MapContainer = ({ google }) => {
    let [map, setMap] = useState();

    return <div className="map-container">
        <Map google={google}
            onReady={useCallback((_, map) => { setMap(map); }, [setMap])}
            ...more>
        </Map>
    </div>;
}

Here I have a state variable called map that will hold the map reference. It's set when the onReady callback fires (useCallback may not be necessary but whatever).

once you have the map, you can now interact with it like so:

const MapContainer = ({ google, panToPoint }) => {
    let [map, setMap] = useState();

    useEffect(() => {
        if(map && panToPoint) {
            map.panTo(panToPoint);
        }
    }, [map, panToPoint]);

    return <div className="map-container">
        <Map google={google} ...>
        </Map>
    </div>;
}

Here we use useEffect to do some "imperative" work outside of the functional react world. The stuff inside useEffect will only be called if either map or panToPoint changes. We need to check for map because in the initial render it will not be set, and will only be set after onLoad fires.

There may be other ways to achieve the same result but this works I think.