1

I'm using react-native-maps to render GOOGLE MAPS with loads of markers that I fetch from my co-worker's API. Bellow the map I have a FlatList rendering data from every marker on the screen. The item in FlatList's renderItem is a TouchableOpacity. How can I focus on the marker callout when I press the corresponding button in the list?

ScreenShot:

enter image description here

code:

<Container>
  <StatusBar
    barStyle={theme.colors.statusDark}
    backgroundColor={theme.colors.background1}
  />
  <GoogleMaps>
    {markers.map(marker => (
      <MyMarker
        key={marker.uid}
        identifier={marker.uid}
        markerLatitude={marker.position.lat}
        markerLongitude={marker.position.lng}
        title={marker.name}
        address={marker.address}
        cashback={marker.cashback}
      />
    ))}
  </GoogleMaps>
  <DivisorSimple />
  <ListContainer>
    {fetchIsLoading ? (
      <ActivityIndicator size='large' />
    ) : (
      <FlatList
        data={markers}
        renderItem={({ item }) => (
          <ListMapItem
            handleClick={() => {}
            title={item.name}
            address={item.address}
            cashback={item.cashback}
            handleGetRoute={() => handleGetRoute(item.position.lat, item.position.lng)}
          />
        )}
        keyExtractor={item => item.uid}
      />
    )}
  </ListContainer>
</Container>
LuizfBrisighello
  • 259
  • 4
  • 13

1 Answers1

1

Animating map to marker is done imperatively, so you need to get a reference to your MapView component, e.g. add this prop to MapView:

<MapView
  ...
  ref={ref => this.map = ref}
>
  {data.map(item => <Marker ... />)}
</MapView>

In easiest case, this should refer to the component that is also rendering your Markers, so that you can reference this.map in Marker's render. If your MapView component is wrapped into something else, you will need to forward ref to get the ref to the actual MapView component

Then, you need to keep track of Region currently displayed on a map and it's changes when user moves the camera

<MapView
  ...
  onRegionChangeComplete={region => this.setState({ region })}
>

After that you can use MapView's animateToRegion method to focus on marker

// ListMapItem's handleClick prop
handleClick={() => {
      // construct new region from marker's lat/lng
      // and current region's deltas to keep zoom level
      const newRegion = {
        latitude: item.position.lat,
        longitude: item.position.lng,
        latitudeDelta: this.state.region.latitudeDelta,
        longitudeDelta: this.state.region.latitudeDelta,
      }
      // animate camera to that region over 500 ms
      this.map.animateToRegion(newRegion, 500)
    }}
Max
  • 4,473
  • 1
  • 16
  • 18
  • Thanks a lot! This will probably work but I'm having trouble forwarding refs in my functional component. Is there any way you can help me? – LuizfBrisighello Oct 28 '19 at 13:09
  • Im following this https://stackoverflow.com/questions/57005663/when-to-use-useimperativehandle-uselayouteffect-and-usedebugvalue But im getting `Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?` And it looks like its something with `react-redux` – LuizfBrisighello Oct 28 '19 at 16:15
  • Forwarding refs in functional components differs from that in class components. Take a look here https://reactjs.org/docs/forwarding-refs.html#forwarding-refs-to-dom-components – Max Oct 28 '19 at 16:29
  • Sadly I didnt find any solutions at the official docs, and it doesnt even mention useRef hook. – LuizfBrisighello Oct 28 '19 at 16:51
  • take a look here if you are using hooks https://reactjs.org/docs/hooks-reference.html#useref – Max Oct 28 '19 at 16:56