Search code examples
reactjsgoogle-mapssetstategoogle-maps-react

A specific piece of state does not update - React


I am using the Google Maps Javascript API provided by Google Cloud platfform. The Map Component has an attribute named styles. This attribute tells the map what it should be rendered, like restaurants, parks and more.

The problem is when I call the setState method and update what I want to show in map, differently of the others elements that I have on my state, nothing happens.

Look at one peace of the code to understand what I refering to: This is my method when I don't want to show the defaults poi features on the map

        this.setState({
            showPoiFeatures: false,
            mapTypeStyle: [
                {
                    featureType: "poi",
                    stylers: [{ visibility: "off" }]
                },
            ]
        })
    }

And this is the attribute that I talking above

<Map
    className="map"
    initialCenter={{ lat: -23.0916907, lng: -47.2216777 }}
    zoom={14}
    google={this.props.google}
    onClick={this.onClickMap}
    controlSize="1"
    clickableIcons={false}
    styles={this.state.mapTypeStyle}
>

Here is my initial state:

state = {
        variable1: {},
        variable2: {
            object: {
                variable3: '',
                variable4: 0,
                variable5: 0,
                variable6: 0,
                variable7: '',
                variable8: 0,
                variable9: '',
                variable10: 0,
                variable11: 0
            }
        },
        variable12: true,
        mapTypeStyle: [],
        showPoiFeatures: true,
    }

A empty array means that I want to show all features on the map

If this text got confused, please ask me to explain more. Thanks


Solution

  • The style parameter of the <Map/> takes CSS style object - commonly width and height. If you want the custom map style you need to use the setOptions>styles. Here's a sample code (Note: use an API key for the code to work properly) and a code snippet below on how to achieve this:

    import React, { Component } from "react";
    import { Map, Marker, GoogleApiWrapper } from "google-maps-react";
    
    const mapStyle = [
      {
        featureType: "poi",
        stylers: [{ visibility: "off" }]
      }
    ];
    
    export class MapContainer extends Component {
      constructor(props) {
        super(props);
    
        this.state = {
          mapVariable: true
        };
      }
      _mapLoaded(mapProps, map) {
       
        this.setState({
          mapVariable: map
        });
      }
    
      showStyle = () => {
        this.state.mapVariable.setOptions({
          styles: mapStyle
        });
      };
    
      hideStyle = () => {
        this.state.mapVariable.setOptions({
          styles: null
        });
      };
    
      render() {
        const coords = { lat: 40.712775, lng: -74.005973 };
        const containerStyle = {
          position: "relative",
          width: "600px",
          height: "600px"
        };
    
        return (
          <div>
            <form>
              <input
                type="radio"
                id="show"
                name="choice"
                value="show"
                onClick={this.showStyle}
              />
              <label for="show">Show</label>
              <input
                type="radio"
                id="hide"
                name="choice"
                value="hide"
                onClick={this.hideStyle}
              />
              <label for="hide">Hide</label>
              <br />
            </form>
            <Map
              containerStyle={containerStyle}
              google={this.props.google}
              zoom={16}
              initialCenter={coords}
              onReady={(mapProps, map) => this._mapLoaded(mapProps, map)}
            >
              <Marker position={coords} />
            </Map>
          </div>
        );
      }
    }
    export default GoogleApiWrapper({
      apiKey: "YOUR_KEY"
    })(MapContainer);