🍣
【ReactNative】react-native-maps応用編②「マーカーのonPressイベントとマップのonPressイベント」
はじめに
react-native-maps
の応用編第二弾になります。
バックナンバーは以下の通りです。
今回ですが、react-native-maps
でマーカーを使った場合に遭遇するケースです。
サンプル
例えば以下のようにMap
とMarker
にそれぞれonPress
イベントが設定されているとします。
Test.tsx
import React from 'react';
import { Alert } from 'react-native'
import MapView, { Region, Marker, LatLng } from 'react-native-maps';
const Test: React.FC = () => {
// 初期表示位置
const initialRegion : Region = {
latitude : 35.689521,
longitude : 139.691704,
latitudeDelta : 0.0460,
longitudeDelta : 0.0260,
}
// マーカーの表示位置
const coordinate : LatLng = {
latitude : 35.689421,
longitude :139.691604
}
return(){
<MapView initialRegion={initialRegion} onPress={()=> { Alert.alert("マップを押したよ") }} >
<Marker coordinate={coordinate} onPress={()=>{ Alert.alert("マーカーを押したよ") }} />
</MapView>
}
}
マップを押した場合とマーカーを押した場合でそれぞれ違う処理を行いたいのですが、この書き方だとマーカーを押した場合に 「マップ押下時のイベントも一緒に実行」 されてしまいます。
HTML + JS
の世界でいうところのイベントバブリングが起きている状態です。
対処法はstopPropagation()を使う
これはreact-native-maps
というよりreact-native
の各コンポーネントの仕様のようなもので、当然バブリングを止める手段も用意されています。
onPress
の場合だと引数として押下時のイベントが引数として受け取れる(MapEvent
型)ので、stopPropagation()
を実行します。
<Marker coordinate={coordinate} onPress={(e : MapEvent) => {
// マップにonPressイベントが伝播するのを止める
e.stopPropagation();
Alert.alert("マーカーを押したよ")
}} />
こうすることでマーカーを押した場合に上位要素であるマップのonPress
が呼ばれることを防げます。
まとめ
今回はreact-native-maps
でよく使うマップ・マーカーのonPress
イベントのバブリングとその対処法について紹介しました。
よく見かけるのが 「マップをタップした位置にマーカーを置く」 のと 「マーカーをタップした際に何かしらの処理をする」 ようなアプリです。
その場合、今回の例のようにどちらにもonPress
イベントを設定しないといけないため、バブリングに注意する必要があります。
基本といえばそれまでですが、意外と忘れがちなので気を付けましょう。
Discussion