反应严格模式阻止谷歌地图呈现地理围栏功能。我无法在地图上绘制形状



我有一个React v18.2 (TS)应用程序,我需要向我的用户显示谷歌地图。我需要绘图功能,也就是geofence,这样我的用户就可以在地图上绘制多边形形状。我已经使用@react-google-maps/apiv2.18.1集成了地图,如果我是不是,一切都很完美使用React.StrictMode。有人能帮我解决这个问题吗?我需要我的React.StrictMode打开并且仍然在我的地图上渲染地理围栏UI以便我的用户可以使用它。这与React严格模式有什么关系,有没有办法解决这个问题?

这是我的Map组件:

import { Polygon, GoogleMap, useLoadScript } from '@react-google-maps/api';
import { DrawingManager } from './drawing-manager';
interface MapsProps {
lat: number;
lng: number;
isStatic: boolean;
zoom?: number;
isDrawable?: boolean;
}
interface Shape {
type: string;
path: google.maps.LatLngLiteral[];
radius?: number;
}
const { useRef, useMemo, useState, useCallback } = React;
const __mapMandatoryStyles = { width: '100%', height: '100%' }; // ⌂ Keep it like this and style the parent if needed!
const googleMapsApiKey = process.env.REACT_APP_GOOGLE_MAPS_API_KEY as string;
const libraries: ('drawing' | 'geometry' | 'localContext' | 'places' | 'visualization')[] = [
'drawing',
]; // ⌂ Do NOT touch this type! It comes from the '@react-google-maps/api' lib but it's not exported from there.
export const Map = ({
lat,
lng,
isStatic,
zoom = 15,
isDrawable = false,
}: MapsProps): JSX.Element | null => {
const [shapes, setShapes] = useState<Array<Shape>>([]);
const { isLoaded } = useLoadScript({
id: 'google-map-script',
googleMapsApiKey,
libraries,
});
const mapRef = useRef<google.maps.Map | null>(null);
const drawingManagerRef = useRef(null);
const handleMapLoad = useCallback((map: google.maps.Map) => {
if (mapRef?.current) {
mapRef.current = map;
}
}, []);
const handleDraw = useCallback(
(shape: Shape) => {
setShapes([...shapes, shape]);
},
[shapes]
);
const handleOnPolygonComplete = useCallback(
(polygon: google.maps.Polygon) => {
if (polygon.getPath() !== null) {
const polygonPathArray = polygon.getPath().getArray();
if (polygonPathArray) {
const path = polygonPathArray.map(latLngLiteral => {
return { lat: latLngLiteral.lat(), lng: latLngLiteral.lng() };
});
handleDraw({ path, type: 'polygon' });
}
}
},
[handleDraw]
);
const renderShapes = useCallback(
() =>
shapes.map((shape, idx): JSX.Element | null =>
shape.type === 'polygon' ? (
<Polygon key={idx} path={shape.path.map(latLng => latLng)} />
) : null
),
[shapes]
);
const getMapOptions = useMemo(
() => ({
zoomControl: !isStatic,
scrollwheel: !isStatic,
rotateControl: !isStatic,
clickableIcons: !isStatic,
mapTypeControl: !isStatic,
keyboardShortcuts: !isStatic,
fullscreenControl: !isStatic,
streetViewControl: !isStatic,
disableDoubleClickZoom: isStatic,
isFractionalZoomEnabled: !isStatic,
gestureHandling: isStatic ? 'none' : 'auto',
}),
[isStatic]
);
if (isDrawable) {
return isLoaded ? (
<GoogleMap
zoom={zoom}
center={{ lat, lng }}
options={getMapOptions}
mapContainerStyle={__mapMandatoryStyles}
onLoad={handleMapLoad}
>
<DrawingManager
ref={drawingManagerRef}
options={{
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [google?.maps?.drawing?.OverlayType.POLYGON],
},
}}
onPolygonComplete={handleOnPolygonComplete}
/>
{renderShapes()}
</GoogleMap>
) : null;
}
return isLoaded ? (
<GoogleMap
zoom={zoom}
center={{ lat, lng }}
options={getMapOptions}
mapContainerStyle={__mapMandatoryStyles}
/>
) : null;
};

DrawingManager的代码是:

import * as React from 'react';
import {
DrawingManager as RactGoogleMapsDrawingManager,
DrawingManagerProps,
} from '@react-google-maps/api';
export const DrawingManager = React.forwardRef<RactGoogleMapsDrawingManager, DrawingManagerProps>(
(props, ref): JSX.Element => <RactGoogleMapsDrawingManager ref={ref} {...props} />
);
DrawingManager.displayName = 'DrawingManager';

在React v18和Up中使用DrawingManagerF代替DrawingManager

这是未记录的,但您应该使用F结尾的组件,在您的情况下,是DrawingManagerF。因为旧的组件不兼容React 18.

Ref: 2.10.0 react@18支持,组件的新功能版本

F字母意味着Functional,使用这些组件将使您能够在开发阶段使用React.Strictmode而不会出现DrawingManager的问题。

因为React.Strictmode只在开发阶段使用,你的应用程序应该在生产阶段工作良好,即使你使用旧的DrawingManager组件。但是如果您想在生产过程中使用React.Strictmode,那么您应该使用DrawingManagerF。这适用于您将要使用的所有其他组件。

参考源代码:https://github.com/JustFly1984/react-google-maps-api/blob/develop/packages/react-google-maps-api/src/components/drawing/DrawingManager.tsx

话虽如此,但请注意,由于这里提到的构建问题,公共文档已经过时了。

希望这对你有帮助!