Reputation: 51
I have a map view, and in another componenet, I would like to be able to have a function that animates that mapview. That function would need a reference to my map view. How can I access my maps reference inside another component?
I have a snack expo that reproduces my problem exactly here as well as some code below. Please note which files are classes and which are functions. The files are too big in my projects, I do not want to change them
EDIT: Could I use some sort of state library such as Context to store the ref?
export default function App() {
return (
<View style={styles.container}>
<Map/>
<AnimateMapButton/>
</View>
);
}
I cant access this._map for obvious reasons. How can I access this?
export default class AnimateMapButton extends React.Component {
goToLocation = () => {
this._map.animateToRegion({
latitude: 103.1561,
longitude: -47.1651,
latitudeDelta: 0.0025,
longitudeDelta: 0.0025,
})
}
render() {
return (
<View style={{height: 75, width: 200, backgroundColor: 'red', position: 'absolute', top: 100}}>
<TouchableOpacity onPress={() => this.goToLocation()}>
<Text style={{fontSize: 20, }}>Click to animate the map</Text>
</TouchableOpacity>
</View>
);
}
}
export default class Map extends React.Component {
render(){
return (
<View style={styles.container}>
<MapView
style={styles.map}
ref={map => this._map = map}
/>
</View>
);
}
}
Upvotes: 1
Views: 637
Reputation: 616
I suggest you use React.forwardRef
in such scenarios.
map.js
export default React.forwardRef((props, ref) => {
return (
<View style={styles.container}>
<MapView
ref={ref}
style={styles.map}
/>
</View>
);
})
animatemapbutton.js
export default class AnimateMapButton extends React.Component {
render() {
return (
<View style={{height: 75, width: 200, backgroundColor: 'red', position: 'absolute', top: 100}}>
<TouchableOpacity onPress={() => this.props.onGotoLocation()}>
<Text style={{fontSize: 20, }}>Click to animate the map</Text>
</TouchableOpacity>
</View>
);
}
}
App.js
export default function App() {
const _mapRef = React.createRef();
goToLocation = () => {
_mapRef.current.animateToRegion({
latitude: 103.1561,
longitude: -47.1651,
latitudeDelta: 0.0025,
longitudeDelta: 0.0025,
})
}
return (
<View style={styles.container}>
<Map ref={_mapRef}/>
<AnimateMapButton onGotoLocation={goToLocation} />
</View>
);
}
Upvotes: 1
Reputation: 11244
You have to use a combination of reference and event callback method in the root component like this -
App.js
export default function App() {
const mapRef = React.useRef();
const goToLocation = () => {
mapRef.current.animateToRegion({
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
})
}
return (
<View style={styles.container}>
<Map mapRef={mapRef} />
<AnimateMapButton goToLocation={goToLocation} />
</View>
);
}
animatemapbutton.js
export default function Animatemapbutton({ goToLocation }) {
return (
<TouchableOpacity
style={{ height: 75, width: 200, backgroundColor: 'red', position: 'absolute', top: 100 }}
onPress={() => goToLocation()}
>
<Text style={{fontSize: 20, }}>Click to animate the map</Text>
</TouchableOpacity>
);
}
map.js
export default function Map({ mapRef }) {
return (
<View style={styles.container}>
<MapView
ref={mapRef}
style={styles.map}
/>
</View>
);
}
Upvotes: 0