switch maptype in react-native-map

Viewed 7727

I have the react-native map running with google for both IOS and Android. Is there a way to have the mapType layer switcher like that of google maps app enabled in react-native expo app? So that user can switch mapTypes (standard, satellite, ....)

a simplified version of the code

constructor(props) {
  super(props);
  this.state = {
    mapRegion: null,
    markers: [],
    mapType: null
  };
}

switchMapType() {
  console.log('Changing');
  this.state.mapType = 'satellite'
}

render() {
  return (
    <MapView
      provider="google"
      mapType={this.state.mapType}
    >
      <Icon
        onPress={this.switchMapType} 
      />
    </MapView>
  );
}

I get an undefined error when inside state switchMapType().

1 Answers

Looking at the documentation it can be as simple as passing the correct style to the mapType prop

https://github.com/react-native-community/react-native-maps/blob/master/docs/mapview.md

The map type to be displayed.

  • standard: standard road map (default)
  • none: no map
  • satellite: satellite view
  • hybrid: satellite view with roads and points of interest overlayed
  • terrain: (Android only) topographic view
  • mutedStandard: more subtle, makes markers/lines pop more (iOS 11.0+ only)

Binding you function

You are getting that error because probably need to bind your function so that it knows that value of this to use. You can do it in your constructor by putting the following in your constructor

constructor(props) {
  ...
  this.switchMapType = this.switchMapType.bind(this);    
  ...
}

or you could convert switchMapType to an arrow function by changing its declaration to

switchMapType = () => {
  ...
}

or you could bind the function when you call it

<Icon
  onPress={this.switchMapType.bind(this} 
/>

You can see this article for more details https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

I prefer to use arrow functions myself.

Setting State

I also notice that there is an error in your function switchMapType with how you are setting state. You are calling this.state.mapType = 'satellite' You should not manipulate state like this. Changing state like this will not force a re-render (which is what you want) and it can lead to unexpected consequences. See this article for more on setting state https://medium.com/@baphemot/understanding-reactjs-setstate-a4640451865b

If you want to change the state you should use this.setState({ key1: value1, key2, value2 });

So if you update your switchMapType function to be the following it should work

switchMapType = () => {
  console.log('changing');
  this.setState({ mapType: 'satellite' });
}

If you want to be able to toggle between the satellite and standard versions you could do something like this. This uses a ternary statement to handle the if/else https://codeburst.io/javascript-the-conditional-ternary-operator-explained-cac7218beeff

switchMapType = () => {
  console.log('changing');
  this.setState({ mapType: this.state.mapType === 'satellite' ? 'standard' : 'satellite' });
}
Related