Thomas Wong
Thomas Wong

Reputation: 1

react-google-maps map refreshes after onclick

I'm using react-google-maps in a Map component and whenever I click on a marker two odd things happen. First, there is two InfoWindow's opening, one blank one and one with my div. Also, whenever an onclick is performed the map refreshes which is not what I want. I am calling my Map component from App.js.

import React, { useState, Component } from'react';
import { GoogleMap, withScriptjs, withGoogleMap, Marker, InfoWindow } from "react-google-maps";

    function Map(props) {
        const WrappedMap = withScriptjs(withGoogleMap(CreateMap))
        const [selectedPatio, setSelectedPatio] = useState(null)

        function CreateMap(){
            return (
                <GoogleMap
                    defaultZoom={13}
                    defaultCenter={{ lat: 49.278352, lng: -123.122538 }}
                >
                {props.patios.map((patio) => (
                    <Marker 
                        key={patio.name}
                        position={{
                            lat: patio.lat, 
                            lng: patio.lng}}
                        onClick={() => {
                            setSelectedPatio(patio);
                        }}
                    />
                ))}

                {selectedPatio && (
                    <InfoWindow
                    onCloseClick={() => {
                        setSelectedPatio(null);
                    }}
                    position={{
                        lat: selectedPatio.lat,
                        lng: selectedPatio.lng
                    }}
                    >
                    <div>
                        asd
                    </div>
                    </InfoWindow>
                )}
                </GoogleMap>)
        }

        return (
            <WrappedMap
            googleMapURL={'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=gemotry,drawing,places&key=XXX'}
            loadingElement={<div style={{ height: `100%` }} />}
            containerElement={<div style={{ height: `100%` }} />}
            mapElement={<div style={{ height: `100%` }} />}
    />
        );
    }

export default Map

//This is what my render looks like in app.js where i'm calling Map and sending an array of patios to props

render() {
    return (
        <BrowserRouter>      
        <NavBar data={{ icon:"location", text1:"Map", text2:"About"}}></NavBar>
        <div style={{  width: `100vw` , height: `75vh`, maxWidth: `100%` }}>
        <Map patios={this.state.patios}/>
        <div>
          <PatioMasonry patios={this.state.patios}/>
        </div>
        </div>
        <div>
          <BottomNavBar/>
        </div>
        <div>
            <Switch>
              <Route path="/" component={Homescreen} exact/>
           </Switch>
        </div> 
      </BrowserRouter>
    );
  }
}

Upvotes: 0

Views: 1592

Answers (1)

gdh
gdh

Reputation: 13702

You are defining a functional component inside another functional component. By doing this, when the parent component re-renders, then a new instance of child component is created and the component is re-mounted instead of re-render. Therefore your map is getting refreshed.

Move your CreateMap component outside of Map component

import React, { useState, Component } from'react';
import { GoogleMap, withScriptjs, withGoogleMap, Marker, InfoWindow } from "react-google-maps";

const WrappedMap = withScriptjs(withGoogleMap(CreateMap))

function CreateMap(){
    const [selectedPatio, setSelectedPatio] = useState(null)    
    return (
        <GoogleMap
            defaultZoom={13}
            defaultCenter={{ lat: 49.278352, lng: -123.122538 }}
        >
        {props.patios.map((patio) => (
            <Marker 
                key={patio.name}
                position={{
                    lat: patio.lat, 
                    lng: patio.lng}}
                onClick={() => {
                    setSelectedPatio(patio);
                }}
            />
        ))}

        {selectedPatio && (
            <InfoWindow
            onCloseClick={() => {
                setSelectedPatio(null);
            }}
            position={{
                lat: selectedPatio.lat,
                lng: selectedPatio.lng
            }}
            >
            <div>
                asd
            </div>
            </InfoWindow>
        )}
        </GoogleMap>)
}
    function Map(props) {

        return (
            <WrappedMap
            googleMapURL={'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=gemotry,drawing,places&key=XXX'}
            loadingElement={<div style={{ height: `100%` }} />}
            containerElement={<div style={{ height: `100%` }} />}
            mapElement={<div style={{ height: `100%` }} />}
            />
        );
    }

export default Map

Upvotes: 2

Related Questions