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
});
};
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)}
/>
));
};
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.