Skip to content

Commit 5a26cd8

Browse files
committed
chore(example): memoize callbacks
1 parent 7c1d48d commit 5a26cd8

File tree

5 files changed

+256
-131
lines changed

5 files changed

+256
-131
lines changed

example/src/components/MapWrapper.tsx

Lines changed: 6 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,39 @@
1-
import React, { useMemo } from 'react';
1+
import React, { useMemo, useState } from 'react';
22
import type { ViewProps } from 'react-native';
33
import { ActivityIndicator, StyleSheet, View } from 'react-native';
44
import type {
55
GoogleMapsViewRef,
6-
RNCamera,
76
RNGoogleMapsPlusViewProps,
87
RNInitialProps,
9-
RNLatLng,
10-
RNLocation,
118
RNLocationConfig,
129
RNMapPadding,
1310
RNMapUiSettings,
1411
RNMapZoomConfig,
15-
RNRegion,
16-
RNIndoorBuilding,
17-
RNIndoorLevel,
1812
} from 'react-native-google-maps-plus';
1913
import {
2014
GoogleMapsView,
2115
RNAndroidLocationPriority,
2216
RNIOSLocationAccuracy,
2317
RNIOSLocationActivityType,
24-
RNLocationErrorCode,
25-
RNMapErrorCode,
2618
} from 'react-native-google-maps-plus';
2719
import { useSafeAreaInsets } from 'react-native-safe-area-context';
28-
import { callback } from 'react-native-nitro-modules';
2920
import type { AppTheme } from '../theme';
3021
import { useAppTheme } from '../hooks/useAppTheme';
22+
import { useMapCallbacks } from '../hooks/useMapCallbacks';
3123

3224
type Props = ViewProps &
3325
RNGoogleMapsPlusViewProps & {
3426
mapRef: React.RefObject<GoogleMapsViewRef | null>;
3527
children?: React.ReactNode;
3628
};
3729

38-
function wrapCallback<T extends (...args: any[]) => void>(
39-
propCallback: T | undefined,
40-
fallback?: (...args: Parameters<T>) => void
41-
) {
42-
return callback({
43-
f: ((...args: Parameters<T>) => {
44-
propCallback?.(...args);
45-
fallback?.(...args);
46-
}) as T,
47-
});
48-
}
49-
5030
export default function MapWrapper(props: Props) {
5131
const { children, ...rest } = props;
5232
const theme = useAppTheme();
5333
const styles = useMemo(() => getThemedStyles(theme), [theme]);
5434
const layout = useSafeAreaInsets();
5535

56-
const [mapLoaded, setMapLoaded] = React.useState(false);
36+
const [mapLoaded, setMapLoaded] = useState(false);
5737
const initialProps: RNInitialProps = useMemo(
5838
() => ({
5939
camera: {
@@ -110,11 +90,12 @@ export default function MapWrapper(props: Props) {
11090
[]
11191
);
11292

93+
const mapCallbacks = useMapCallbacks(props, props.mapRef, setMapLoaded);
94+
11395
return (
11496
<View style={styles.container}>
11597
<GoogleMapsView
11698
{...rest}
117-
hybridRef={wrapCallback((ref) => (props.mapRef.current = ref))}
11899
initialProps={props.initialProps ?? initialProps}
119100
uiSettings={props.uiSettings ?? uiSettings}
120101
myLocationEnabled={props.myLocationEnabled ?? true}
@@ -129,108 +110,7 @@ export default function MapWrapper(props: Props) {
129110
mapZoomConfig={props.mapZoomConfig ?? mapZoomConfig}
130111
mapPadding={props.mapPadding ?? mapPadding}
131112
locationConfig={props.locationConfig ?? locationConfig}
132-
onMapError={wrapCallback(props.onMapError, (e: RNMapErrorCode) =>
133-
console.log('Map error:', e)
134-
)}
135-
onMapReady={wrapCallback(props.onMapReady, (ready: boolean) =>
136-
console.log('Map is ready:', ready)
137-
)}
138-
onMapLoaded={wrapCallback(
139-
props.onMapLoaded,
140-
(region: RNRegion, camera: RNCamera) => {
141-
console.log('Map is loaded:', region, camera);
142-
setMapLoaded(true);
143-
}
144-
)}
145-
onMapPress={wrapCallback(props.onMapPress, (c: RNLatLng) =>
146-
console.log('Map press:', c)
147-
)}
148-
onMapLongPress={wrapCallback(props.onMapLongPress, (c: RNLatLng) =>
149-
console.log('Map long press:', c)
150-
)}
151-
onPoiPress={wrapCallback(
152-
props.onPoiPress,
153-
(placeId: string, name: string, coordinate: RNLatLng) =>
154-
console.log('Poi press:', placeId, name, coordinate)
155-
)}
156-
onMarkerPress={wrapCallback(props.onMarkerPress, (id: string) =>
157-
console.log('Marker press:', id)
158-
)}
159-
onPolylinePress={wrapCallback(props.onPolylinePress, (id: string) =>
160-
console.log('Polyline press:', id)
161-
)}
162-
onPolygonPress={wrapCallback(props.onPolygonPress, (id: string) =>
163-
console.log('Polygon press:', id)
164-
)}
165-
onCirclePress={wrapCallback(props.onCirclePress, (id: string) =>
166-
console.log('Circle press:', id)
167-
)}
168-
onMarkerDragStart={wrapCallback(
169-
props.onMarkerDragStart,
170-
(id: string, latLng: RNLatLng) =>
171-
console.log('Marker drag start:', id, latLng)
172-
)}
173-
onMarkerDrag={wrapCallback(
174-
props.onMarkerDrag,
175-
(id: string, latLng: RNLatLng) =>
176-
console.log('Marker drag:', id, latLng)
177-
)}
178-
onMarkerDragEnd={wrapCallback(
179-
props.onMarkerDragEnd,
180-
(id: string, latLng: RNLatLng) =>
181-
console.log('Marker drag end:', id, latLng)
182-
)}
183-
onIndoorBuildingFocused={wrapCallback(
184-
props.onIndoorBuildingFocused,
185-
(building: RNIndoorBuilding) =>
186-
console.log('Indoor building focused:', building)
187-
)}
188-
onIndoorLevelActivated={wrapCallback(
189-
props.onIndoorLevelActivated,
190-
(level: RNIndoorLevel) =>
191-
console.log('Indoor level activated:', level)
192-
)}
193-
onInfoWindowPress={wrapCallback(props.onInfoWindowPress, (id: string) =>
194-
console.log('InfoWindow press:', id)
195-
)}
196-
onInfoWindowClose={wrapCallback(props.onInfoWindowClose, (id: string) =>
197-
console.log('InfoWindow close:', id)
198-
)}
199-
onInfoWindowLongPress={wrapCallback(
200-
props.onInfoWindowLongPress,
201-
(id: string) => console.log('InfoWindow long press:', id)
202-
)}
203-
onMyLocationPress={wrapCallback(
204-
props.onMyLocationPress,
205-
(location: RNLocation) => console.log('MyLocation press:', location)
206-
)}
207-
onMyLocationButtonPress={wrapCallback(
208-
props.onMyLocationButtonPress,
209-
(pressed: boolean) => console.log('MyLocation button press:', pressed)
210-
)}
211-
onCameraChangeStart={wrapCallback(
212-
props.onCameraChangeStart,
213-
(r: RNRegion, cam: RNCamera, g: boolean) =>
214-
console.log('Camera start:', r, cam, g)
215-
)}
216-
onCameraChange={wrapCallback(
217-
props.onCameraChange,
218-
(r: RNRegion, cam: RNCamera, g: boolean) =>
219-
console.log('Camera changed:', r, cam, g)
220-
)}
221-
onCameraChangeComplete={wrapCallback(
222-
props.onCameraChangeComplete,
223-
(r: RNRegion, cam: RNCamera, g: boolean) =>
224-
console.log('Camera complete:', r, cam, g)
225-
)}
226-
onLocationUpdate={wrapCallback(
227-
props.onLocationUpdate,
228-
(l: RNLocation) => console.log('Location:', l)
229-
)}
230-
onLocationError={wrapCallback(
231-
props.onLocationError,
232-
(e: RNLocationErrorCode) => console.log('Location error:', e)
233-
)}
113+
{...mapCallbacks}
234114
/>
235115
{children}
236116
{!mapLoaded && (

0 commit comments

Comments
 (0)