maps
maps copied to clipboard
A bug occurs when using @react-navigation/material-bottom-tabs and @react-native-mapbox-gl/maps
Describe the bug
- When I use @react-navigation/material-bottom-tabs with @react-native-mapbox-gl/maps , there is bug when I navigate to screen with MapView: it srinks to ~5px
To Reproduce
- create react native project
- install @react-navigation/material-bottom-tabs @react-native-mapbox-gl/maps
- copy and paste my code
- navigate a few times beetwen 2 screens by the bottom tab (should navigate Map > (other screen) > Map, first time you navigate to the map, it works fine. Bug happens on second time)
Example:
App.tsx
import { NavigationContainer } from '@react-navigation/native';
import { LocationsStackScreen } from './app/views/LocationsStackScreen';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { MapScreen } from './app/views/MapScreen';
const Tab = createMaterialBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="LocationsStack"
>
<Tab.Screen
name="LocationsStack"
component={LocationsStackScreen}
options={{
title: "Locations",
tabBarIcon: 'map-marker',
}}
/>
<Tab.Screen
name="Map"
component={MapScreen}
options={{
tabBarIcon: 'map',
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;
/views/MapScreen.tsx
import React from "react"
import { StyleSheet, View } from "react-native"
import MapboxGL from "@rnmapbox/maps";
MapboxGL.setAccessToken("pk.eyJ1IjoiYnVzeXN0cmlrZSIsImEiOiJjbDF6ZGlnYXQwa2J5M2luc2ZtdjJ5cGNsIn0.sZR8atlffH27nYUuq5sNig");
const styles = StyleSheet.create({
page: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
container: {
height: 300,
width: 300,
backgroundColor: "tomato"
},
map: {
flex: 1
}
});
export const MapScreen = () => {
return (
<View style={styles.page}>
<View style={styles.container}>
<MapboxGL.MapView style={styles.map} />
</View>
</View>
);
}
/views/LocationsStackView.tsx
import React from 'react';
import { Text } from 'react-native';
export const LocationsStackScreen = () => {
return (
<Text>Locations stack view</Text>
)
}
Startup:
npx react-native init MyApp --template react-native-template-typescript
cd MyApp
yarn add rnmapbox/maps#main
yarn add @react-navigation/native
yarn add react-native-screens react-native-safe-area-context
yarn add @react-navigation/material-bottom-tabs
react-native run-android
Expected behavior
I expected the map which doesn't shrink when I navigate between pages
Actual behavior
The map shrinks when I navigate between pages (when I first time navigate to the screen with the map, it doesn't srink, it happens only on second time)
Screenshots

Versions (please complete the following information):
- Platform: [Android]
- Platform OS: [Android 11]
- Device: [Realme 8]
- Emulator/ Simulator: [using physical device]
- Dev OS: [Win10]
- @rnmapbox/maps Version [rnmapbox/maps#main] (i don't know how to check)
- Mapbox GL version [latest] (i don't know how to check)
- React Native Version [0.68]
Additional context
If I use @react-navigation/material-bottom-tabs instead of @react-navigation/material-bottom-tabs, when I second time go to the map screen, the application freezes and then crashes.
But if I use custom bottom tabs navigation (https://reactnavigation.org/docs/custom-navigators) it works without the bug
I experience the same freeze&crash with @react-navigation/bottom-tabs latest version, and the same shrinking with @react-navigation/material-bottom-tabs
I've also come across the same freeze and crash issue with @react-navigation/bottom-tabs and the same versions of Android and React. To work around the issue, I used the useIsFocused hook to unmount the map when screen containing it lost focus, and remount it when focus was regained. This appeared to be unnecessary on iOS, as the issue didn't occur.
I can't add anything to the shrinking issue as I'm not using @react-navigation/material-bottom-tabs
Your workaround seems to do the trick @Dru1X , thanks
same issue here on Android and react-navigation. When a new screen is pushed on top of a screen with a Map rendered and the user presses "back" (navigation.goBack()) the app freezes and crashes. as a workaround we preserve the zoom, center, and bounds of the map and unmount onWillBlur of the view; however, this isn't ideal of course as it impacts performance and requires unnecessary state management.
Same issue for us as well, and a pretty significant one. Will try to save camera state between focus / unfocus. Hope for a quick resolution! 👨🏼🔬
Quick example on how to store camera state and restore it:
const isFocus = useIsFocused()
const camera = useRef(null)
const [zoomInfo, setZoomInfo] = useState(9)
const [centerInfo, setCenterInfo] = useState([0, 0])
useEffect(() => {
if (isFocus && zoomInfo !== 9) {
camera.current?.setCamera({zoomLevel: zoomInfo, centerCoordinate: centerInfo})
}
}, [isFocus])
const changedView = ({properties, geometry}) => {
if (zoomInfo !== properties.zoomLevel) {
setZoomInfo(properties.zoomLevel)
setCenterInfo(geometry?.coordinates)
}
}
(...)
<Map ref={map} onRegionDidChange={changedView}>
<MapboxGL.Camera
defaultSettings={{zoomLevel: zoomInfo, centerCoordinate: centerInfo}}
ref={camera}
/>
I think it's because MapView unmounts incorrectly. If turn off detaching screens app does not freeze.
<Tab.Navigator detachInactiveScreens={false}>...</Tab.Navigator>
Referencing to https://stackoverflow.com/a/49351100/7024360
When using stack navigator the same thing happens when navigating back to mapView screen. When navigating away from the mapView screen I set the detachPreviousScreen property on Stack.Navigator screen options to false. This fixed the issue for me.
<Stack.Navigator
screenOptions={{
detachPreviousScreen: routeNameRef.current === 'Home' ?? false,
}}>
Duplicate of #2212