maps icon indicating copy to clipboard operation
maps copied to clipboard

A bug occurs when using @react-navigation/material-bottom-tabs and @react-native-mapbox-gl/maps

Open Carabine opened this issue 3 years ago • 4 comments
trafficstars

Describe the bug

  1. 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

  1. create react native project
  2. install @react-navigation/material-bottom-tabs @react-native-mapbox-gl/maps
  3. copy and paste my code
  4. 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
image image

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

Carabine avatar Jun 07 '22 12:06 Carabine

I experience the same freeze&crash with @react-navigation/bottom-tabs latest version, and the same shrinking with @react-navigation/material-bottom-tabs

felixgourdeau avatar Jun 22 '22 01:06 felixgourdeau

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

Dru1X avatar Jun 22 '22 09:06 Dru1X

Your workaround seems to do the trick @Dru1X , thanks

felixgourdeau avatar Jun 22 '22 12:06 felixgourdeau

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.

wen-kai avatar Jul 07 '22 20:07 wen-kai

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}
    />

nixolas1 avatar Aug 15 '22 09:08 nixolas1

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

Crysp avatar Aug 29 '22 08:08 Crysp

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,
     }}>

FrancoisVA avatar Sep 07 '22 06:09 FrancoisVA

Duplicate of #2212

mfazekas avatar Sep 16 '22 08:09 mfazekas