1

I was using the original react-google-maps package for a while but realized it hadn't been updated for a a couple years so i installed an updated package called react-google-maps/api. Both packages have a component called <GoogleMap/> but the old package had a prop you could pass to it called defaultCenter. Declaring this property would make it so that when the map component mounted, this value would be the center but would not change the center when the component re-rendered. This new package only seems to have a prop called center and the map will go back to this value whenever it re-renders. Heres the code illustrating my problem:

import { GoogleMap, LoadScript } from '@react-google-maps/api'

function App() {

  const [someState, setSomeState] = useState(false);

  return (
    <div className="App">
      <button className="" onClick={() => {someState ? setSomeState(false) : setSomeState(true)}}>Click</button>
      <LoadScript
        id="script-loader"
        googleMapsApiKey=""
      >
        <GoogleMap
          id='example-map'
          mapContainerStyle={{
            height: '900px',
            width: '900px'}}
          center={{lat:41, lng: -71}}
          zoom={4}
        >
        </GoogleMap>
      </LoadScript>
    </div>
  );
}

export default App;

here's what happens:
1) Page loads to specified center
2) I drag the map to a different location
3) I press the button that changes the state
4) The map reloads back to the original center

how can I get the map to stay at its current location when i press the button that sets the state?

AndoKay
  • 57
  • 2
  • 9

1 Answers1

4

That is to be expected. When the component <App/> is re-rendered, so is the <GoogleMap/> component inside.

You can retrieve the map instance with the onLoad prop and the useRef hook, so you can use the instance with .current property and have the center in state.

When a user drags the map (triggering onDrag, onDragEnd and onDragStart events) you can set the new center with the ref instance you saved.

function App() {
  const mapRef = useRef(null);
  const [position, setPosition] = useState({
      lat: 41, 
      lng: -71
  });

  function handleLoad(map) {
    mapRef.current = map;
  }

  function handleCenter() {
    if (!mapRef.current) return;

    const newPos = mapRef.current.getCenter().toJSON();
    setPosition(newPos);
  }

  return (
    <GoogleMap
      zoom={4}
      onLoad={handleLoad}
      onDragEnd={handleCenter}
      center={position}
      id="map"
      mapContainerStyle={{
        height: '900px',
        width: '900px'
      }}
    >
   </GoogleMap>
  );
}
Slavian
  • 254
  • 1
  • 9
  • thank you so much! The only thing is that if `onCenterChanged` triggers `handleCenter` it seems to cause an infinite loop. I was able to get it to work just leaving that out. However I guess this might be a problem if the center changes due to something other than a drag event. – AndoKay May 06 '20 at 00:27
  • Opsss... mistake from my side. Forgot to remove the onCenterChanged prop. Otherwise as you said it will cause an infinite loop. – Slavian May 06 '20 at 13:50
  • to prevent the infinite loop you can add the following check `if (newPos.lat === position.lat && newPos.lng === position.lng) return` to the `handleCenter` function – Alvaro Blanco May 26 '21 at 03:44