Reputation: 1728
Is there a way to access the ref property from MapView component from an outside function?
Basically, I have:
A main component which has a render method that will call (<MyMap />)
<MyMap />
is an exported function with the MapView Component. Inside the MapView component, I make a reference (ref=map=>(mapRef=map)
and want to pass that reference to the function that generates my markers (<PinData />
.
<PinData />
, I want to use the onPress event for
the marker to zoom in and move to the marker using the
MapView.animateToRegion method.I keep getting the undefined is not an object (evaluating 'mapRef.animateToRegion').
Do I have to create component classes (instead of using exported functions) for the map reference to work in order to render the MapView and Markers components?
Ex: Main Class component:
render(){
return(
<View>
<MyMap region={this.state.region}
pinData={this.state.pinsData}
myPins={this.state.myPins}
mapRef={this._mapRef} />
</View>
)}
MyMap function renders my MapView component.
export const MyMap= ({ region, pinsData, myPins}) => {
return (
<View style={styles.container}>
<MapView
provider={PROVIDER_GOOGLE}
ref={map => (mapRef = map)}
style={styles.userMap}
region={region}
>
<PinData pinsData={pinsData} myPins={myPins} />
</MapView>
</View>
);
PinData Function which is used to generate markers on my map.
export const PinData = ({ pinsData, myPins, mapRef }) => {
return pinsData.map((pin, index) => (
<Marker
key={index}
ref={ref => (markers[index] = ref)}
coordinate={{
longitude: pin.coordinates.lng,
latitude: pin.coordinates.lat
}}
onPress={focusMarker(mapRef, pin, index)}
/>
));
};
onPress function which would zoom into one of the pins using the animateToRegion method associated with the MapView object.
focusMarker = (mapRef, location, index) => {
mapRef.animateToRegion({
latitude: location.coordinates.lat,
longitude: location.coordinates.lng,
latitudeDelta: 0.005,
longitudeDelta: 0.005
});
};
Upvotes: 0
Views: 1227
Reputation: 1728
I figured it out, thanks to Tuan's answer. The code above works. What I wasnt understanding before is how the onPress worked. Basically, from my understanding, the logic is as follows:
Within the MyMap function, we define the focusMarker function.
Then create a prop within the called onPress and set it equal to the focusMarker function.
In the PinData function, we now take this prop(onPress) in as a parameter and set the onPress prop in the Marker component to an anonymous function which will execute the focusMarker function with a parameter of pin. In this function, onPress which is passed in as a parameter for the exported function is actually the focusMarker function itself and we are calling it with a parameter of pin. Hope that makes sense to anyone who can utilize this. Thanks again Tuan. Appreciate it. I was stumped on this for a while.
Upvotes: 0
Reputation: 4162
You can pass an onPress
prop to PinData
export const MyMap= ({ region, pinsData, myPins}) => {
const mapRef = useRef();
focusMarker = (location) => {
mapRef.current.animateToRegion({
latitude: location.coordinates.lat,
longitude: location.coordinates.lng,
latitudeDelta: 0.005,
longitudeDelta: 0.005
});
};
return (
<View style={styles.container}>
<MapView
provider={PROVIDER_GOOGLE}
ref={mapRef}
style={styles.userMap}
region={region}
>
<PinData pinsData={pinsData} myPins={myPins} onPress={focusMarker}/>
</MapView>
</View>
);
}
export const PinData = ({ pinsData, myPins, onPress }) => {
return pinsData.map((pin, index) => (
<Marker
key={index}
ref={ref => (markers[index] = ref)}
coordinate={{
longitude: pin.coordinates.lng,
latitude: pin.coordinates.lat
}}
onPress={() => onPress(pin)}
/>
));
};
Upvotes: 0