0

I have a <MapView /> next to some position: absolute Views with Text in them. In the MapView, I have a <Circle /> within it to mark an area within the map. I have information like the user's coordinates on the overlaid text, as well as if the user is within the radius of the circle area on the map.

I want to be able to change the text being overlaid on top of the MapView without forcing a redraw of the map. Whenever the text changes, the map redraws itself, which resets the user's zoom and makes it disappear momentarily.

The text/view components are not within each other and are side by side for hierarchy.

The Location of the player is drawn on the MapView component with showUserLocation={true}. The actual coordinates are given to the Text components to display to the user with a Location.watchPositionAsync()

const myComponent = () => {
  const [location, setLocation] = useState(null);
  const [circle, setCircle] = useState({
    radius: 5,
    latitude: 0,
    longitude: 0,
  });

  // subscription to the users location
  useEffect(() => {
    subscription = await Location.watchPositionAsync(
      callback: (newLocation) => {
        setLocation(newLocation)
      }
    )
  }

  const isInCircleRadius() => {
    // return true/false based on if user is within the radius of the MapView Circle
  }

  return (
    <>
      <MapView 
        style={{ /* fullscreen all that stuff */ }}
        showUserLocation={true}>
          <Circle radius={circle.radius} center={circle.latitude, circle.longitude} />
      </MapView>
      <View>
        // Text changing here causes the MapView to redraw as well, even though this is just 
        // position: absolute and beside the MapView component
        <Text>{location.latitude} {location.longitude} {isInCircleRadius(location)}
      </View>
    </>
  )

}

I tried making the MapView into its own component and calling it within a parent component to hold the text and map component.

I tried making a local Location variable, so only the Text component reads TextSpecificLocation and the MapView can use MapSpecificLocation even though they have the exact same data. Just to make it so they don't rely on the same variable.

2 Answers 2

0

useEffect without dependency array will lead to a new execution each time call setLocation.

  // subscription to the users location
  useEffect(() => {
    subscription = await Location.watchPositionAsync(
      callback: (newLocation) => {
        setLocation(newLocation)
      }
    )
   },[]) // Add empty dependency array
1
  • This was a good start but unfortunately did not solve the problem of the map rerendering.
    – Apoptosome
    Commented Jun 24 at 15:04
0

The solution was to memoize the MapView into a component and make the dependency array only what changes on the map (the circle area). And then memoize the entire screen surrounding the text and the map with a dependency array of the mutable variables there.

Very stringy problem for anyone to gather enough context on here, so thank you for your efforts.

const MapComponent = useMemo(() => {
  return (
    <MapView>
      <Circle radius={circleInfo.radius} latitude={...} longitude={...} />
    </MapView>
}, [circleInfo]);

const MainScreen = useMemo(() => {
  return (
    <View>
      <MapComponent />
      <OverLayedText tellPlayerIfSafe={isSafe} />
    </view>
  );
}, [MapComponent, isSafe, location]);

return (<> {MainScreen} </>);

Not the answer you're looking for? Browse other questions tagged or ask your own question.