Search code examples
javascriptreactjsjsxreact-google-maps

react-google-maps/api Avoiding re-render of Map after some state changes


I was having problems where my GoogleMaps instance would refresh and self center itself on some onClick function where the state was being set and the entire Component rendering cycle would happen.

After some Googling it was suggested that the component instantiation be separated and re-used. The problem now is I have some logic to display markers inside <GoogleMaps> component that is no longer working as expected and I don't know how to refactor:

export default function LocationSearchResults({
    ...
    }) {
    const [map, setMap] = useState(null)
    const [markersContainer, setMarkersContainer] = useState([])

    const getMap = () => {

        if (map) {
            return map;
        } else {
            setMap(<GoogleMap mapContainerStyle={containerStyle}
                options={ {
                        minZoom: 3,
                        maxZoom: 15
                    }}
                center={{
                        lat: 49.25,
                        lng: -84.5
                    }}
                zoom={5}
                onLoad={onLoad}
                onDragEnd={onDragEnd} >
                {
                    markersContainer.map(place => { //Only executes once? Does not listen for changes
                        return (< Marker key={place.id}
                            position={ place.position}
                        />
                        )
                    })

                }

                </GoogleMap>

                )

                return map

            }
        }

        render( <div className="..." >
                    {
                     getMap()
                    } 
            </div>
        )
    }

I don't have a ton of experience with React, any help is appreciated thanks!


Solution

  • I set up my component instantiation like so using useMemo

    ...instantiate all event listener functions here
    
    const map = useMemo(() =>
     {
       return (<GoogleMap
        mapContainerStyle={containerStyle}
        options={{ minZoom: 3, maxZoom: 15 }}
        center={{
          lat: 49.25,
          lng: -84.5
        }
        }
        zoom={5}
        onLoad={onLoad}
        onDragEnd={onDragEnd}
      // onUnmount={onUnmount}
      >
         {markersContainer.map(place => { return ( <Marker
                        key={place.id}
                        position={place.position} />
                        )
                       })
        }
     </GoogleMap>)
    
    }, [markersContainer])
    

    then I simply render in my render() function:

    return (
        <>
    <div>...
      {map}
    </div>
    </>)
    

    No more unnecessary refreshes unless new markers are added/removed.