From ebf64a767c7b86658ad08d4ffd963912e2bbfd63 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Thu, 6 Jan 2022 19:07:26 -0800 Subject: [PATCH] [v7] Bug fixes (#1673) --- src/components/layer.ts | 6 ++--- src/components/popup.ts | 2 +- src/components/source.ts | 17 ++++--------- src/components/use-map.tsx | 31 ++++++++++++----------- src/mapbox/mapbox.ts | 3 ++- src/types/index.ts | 23 +++++++++++++++++ src/utils/style-utils.ts | 3 +++ src/utils/transform.ts | 20 +-------------- src/utils/use-isomorphic-layout-effect.ts | 2 +- 9 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/components/layer.ts b/src/components/layer.ts index 4b651295..134215b2 100644 --- a/src/components/layer.ts +++ b/src/components/layer.ts @@ -25,7 +25,7 @@ function updateLayer(map: MapboxMap, id: string, props: LayerProps, prevProps: L if (beforeId !== prevProps.beforeId) { map.moveLayer(id, beforeId); } - if (props.layout !== prevProps.layout) { + if (layout !== prevProps.layout) { const prevLayout = prevProps.layout || {}; for (const key in layout) { if (!deepEqual(layout[key], prevLayout[key])) { @@ -38,7 +38,7 @@ function updateLayer(map: MapboxMap, id: string, props: LayerProps, prevProps: L } } } - if (props.paint !== prevProps.paint) { + if (paint !== prevProps.paint) { const prevPaint = prevProps.paint || {}; for (const key in paint) { if (!deepEqual(paint[key], prevPaint[key])) { @@ -51,7 +51,7 @@ function updateLayer(map: MapboxMap, id: string, props: LayerProps, prevProps: L } } } - if (!deepEqual(props.filter, prevProps.filter)) { + if (!deepEqual(filter, prevProps.filter)) { map.setFilter(id, filter); } if (minzoom !== prevProps.minzoom || maxzoom !== prevProps.maxzoom) { diff --git a/src/components/popup.ts b/src/components/popup.ts index 1ab815e8..33e62626 100644 --- a/src/components/popup.ts +++ b/src/components/popup.ts @@ -94,7 +94,7 @@ function Popup(props: PopupProps) { popup.setLngLat([props.longitude, props.latitude]); } // @ts-ignore - if (props.offset && deepEqual(popup.options.offset, props.offset)) { + if (props.offset && !deepEqual(popup.options.offset, props.offset)) { popup.setOffset(props.offset); } // @ts-ignore diff --git a/src/components/source.ts b/src/components/source.ts index c4aa1deb..cec899bc 100644 --- a/src/components/source.ts +++ b/src/components/source.ts @@ -99,21 +99,14 @@ function Source(props: SourceProps) { return () => { map.off('styledata', forceUpdate); - /* global requestAnimationFrame */ - // Do not remove source immediately because the - // dependent s' componentWillUnmount() might not have been called - // Removing source before dependent layers will throw error - // TODO - find a more robust solution - requestAnimationFrame(() => { - // @ts-ignore - if (map.style && map.style._loaded && map.getSource(id)) { - map.removeSource(id); - } - }); + // @ts-ignore + if (map.style && map.style._loaded && map.getSource(id)) { + map.removeSource(id); + } }; } return undefined; - }, [map, id]); + }, []); // @ts-ignore let source = map && map.style && map.getSource(id); diff --git a/src/components/use-map.tsx b/src/components/use-map.tsx index 6ada4fb8..1f1f2b9a 100644 --- a/src/components/use-map.tsx +++ b/src/components/use-map.tsx @@ -14,24 +14,25 @@ export const MountedMapsContext = React.createContext(n export const MapProvider: React.FC<{}> = props => { const [maps, setMaps] = useState<{[id: string]: MapRef}>({}); - const onMapMount = useCallback( - (map: MapRef, id: string = 'default') => { - if (maps[id]) { + const onMapMount = useCallback((map: MapRef, id: string = 'default') => { + setMaps(currMaps => { + if (currMaps[id]) { throw new Error(`Multiple maps with the same id: ${id}`); } - setMaps({...maps, [id]: map}); - }, - [maps] - ); + return {...currMaps, [id]: map}; + }); + }, []); - const onMapUnmount = useCallback( - (id: string = 'default') => { - const nextMaps = {...maps}; - delete nextMaps[id]; - setMaps(nextMaps); - }, - [maps] - ); + const onMapUnmount = useCallback((id: string = 'default') => { + setMaps(currMaps => { + if (currMaps[id]) { + const nextMaps = {...currMaps}; + delete nextMaps[id]; + return nextMaps; + } + return currMaps; + }); + }, []); return ( Transform; + resize: (width: number, height: number) => void; + isPaddingEqual: (value: PaddingOptions) => boolean; + getBounds: () => LngLatBounds; + locationPoint: (lngLat: LngLat) => Point; + pointLocation: (p: Point) => LngLat; +}; diff --git a/src/utils/style-utils.ts b/src/utils/style-utils.ts index b668aa5a..506623c0 100644 --- a/src/utils/style-utils.ts +++ b/src/utils/style-utils.ts @@ -15,6 +15,9 @@ export function normalizeStyle(style: string | MapboxStyle | ImmutableLike): str if ('toJS' in style) { style = style.toJS() as MapboxStyle; } + if (!style.layers) { + return style; + } const layerIndex = {}; for (const layer of style.layers) { diff --git a/src/utils/transform.ts b/src/utils/transform.ts index f8e55811..036fb0ec 100644 --- a/src/utils/transform.ts +++ b/src/utils/transform.ts @@ -1,25 +1,7 @@ import mapboxgl from './mapboxgl'; import type {MapboxProps} from '../mapbox/mapbox'; -import type {PaddingOptions, ViewState} from '../types'; - -/** - * Stub for mapbox's Transform class - * https://github.com/mapbox/mapbox-gl-js/blob/main/src/geo/transform.js - */ -export type Transform = { - width: number; - height: number; - center: {lng: number; lat: number}; - zoom: number; - bearing: number; - pitch: number; - padding: PaddingOptions; - - clone: () => Transform; - resize: (width: number, height: number) => void; - isPaddingEqual: (value: PaddingOptions) => boolean; -}; +import type {Transform, ViewState} from '../types'; /** * Capture a transform's current state diff --git a/src/utils/use-isomorphic-layout-effect.ts b/src/utils/use-isomorphic-layout-effect.ts index 0110143a..9c1e39c4 100644 --- a/src/utils/use-isomorphic-layout-effect.ts +++ b/src/utils/use-isomorphic-layout-effect.ts @@ -2,6 +2,6 @@ // useLayoutEffect but does not trigger warning in server-side rendering import {useEffect, useLayoutEffect} from 'react'; -const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; +const useIsomorphicLayoutEffect = typeof document !== 'undefined' ? useLayoutEffect : useEffect; export default useIsomorphicLayoutEffect;