【发布时间】:2022-10-06 14:48:14
【问题描述】:
我正在使用@googlemaps/react-wrapper 使用googlemaps 中的示例在我的react 应用程序中制作地图组件,并在拖动标记上添加一个事件以刷新坐标,现在可以正常工作。但我需要调用外面的地图组件来用坐标刷新输入值。 我得到的错误是:
绑定元素 \'childToParent\' 隐式具有 \'any\' 类型。* 请帮助我了解如何使用打字稿将值发送给paren 问候 在父母我有这个
const [coordinate,SetCoordinate]=useState(\"\"); return ( <FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}> <Stack spacing={3}> <RHFTextField name=\"lat\" label=\"Coord X\" /> <RHFTextField name=\"lng\" label=\"Coord Y\" /> </Stack> <Stack> <br/> <LocationMap childToParent={setCoordinate}/> </Stack> <Stack> <LoadingButton fullWidth size=\"large\" type=\"submit\" variant=\"contained\" > Save </LoadingButton> </Stack> </FormProvider> );我的位置图组件是这样的
const render = (status: Status) => { return <h1>{status}</h1>; }; interface MapProps extends google.maps.MapOptions { style: { [key: string]: string }; onClick?: (e: google.maps.MapMouseEvent) => void; onIdle?: (map: google.maps.Map) => void; } //function to pass value to parent interface LocationProps { childToParent: (arg0: string)=>string; } export default function LocationMap({childToParent,...props}){ const [clicks, setClicks] = useState<google.maps.LatLng[]>([]); const [zoom, setZoom] = useState(3); // initial zoom const [center, setCenter] = useState<google.maps.LatLngLiteral>({ lat: 0.0, lng: 0.0, }); const [markerLocation, setMarkerLocation] = useState<google.maps.LatLng>(); const dragend = (e: google.maps.MapMouseEvent) => { // avoid directly mutating state setMarkerLocation(e.latLng!) setClicks([...clicks, e.latLng!]); }; const onClick = (e: google.maps.MapMouseEvent) => { }; const onIdle = (m: google.maps.Map) => { //.log(\"onIdle\"); setZoom(m.getZoom()!); setCenter(m.getCenter()!.toJSON()); }; const ref = useRef<HTMLDivElement>(null); const [map, setMap] = useState<google.maps.Map>(); useEffect(() => { if (ref.current && !map) { setMap(new window.google.maps.Map(ref.current, {})); } }, [ref, map]); return ( <> <div style={{ display: \"flex\", height: \"100%\" }}> <Wrapper apiKey={apiKey} render={render}> <Map center={center} onClick={onClick} onIdle={onIdle} zoom={zoom} style={{ flexGrow: \"1\", height: \"25em\", width: \"400px\" }} > <Marker key=\"point\" draggable={true} dragend={dragend} /> </Map> </Wrapper> </div> <div id=\"coordinate\"> {clicks.map(function (latLng, i, row) { var element = document.getElementById(\"coordenadas\"); if (element === null) { console.error(\"error cleaning coordinates\"); } else { element.innerHTML = \"\"; } return ( childToParent(latLng.toJSON()) ); }) } </div> </> ) }; interface MapProps extends google.maps.MapOptions { onClick?: (e: google.maps.MapMouseEvent) => void; onIdle?: (map: google.maps.Map) => void; } const Map: React.FC<MapProps> = ({ onClick, onIdle, children, style, ...options }) => { const ref = useRef<HTMLDivElement>(null); const [map, setMap] = useState<google.maps.Map>(); useEffect(() => { if (ref.current && !map) { setMap(new window.google.maps.Map(ref.current, {})); } }, [ref, map]); // because React does not do deep comparisons, a custom hook is used // see discussion in https://github.com/googlemaps/js-samples/issues/946 useDeepCompareEffectForMaps(() => { if (map) { map.setOptions(options); } }, [map, options]); useEffect(() => { if (map) { [\"click\", \"idle\"].forEach((eventName) => google.maps.event.clearListeners(map, eventName) ); if (onClick) { map.addListener(\"click\", onClick); } if (onIdle) { map.addListener(\"idle\", () => onIdle(map)); } } }, [map, onClick, onIdle]); return ( <> <div ref={ref} style={style} /> {Children.map(children, (child) => { if (isValidElement(child)) { // set the map prop on the child component return cloneElement(child, { map }); } })} </> ); }; interface MarkerProps extends google.maps.MarkerOptions { dragend?: (e: google.maps.MapMouseEvent) => void; } const Marker: React.FC<MarkerProps> = ({ dragend, ...options }) => { const [marker, setMarker] = useState<google.maps.Marker>(); console.log(options); useEffect(() => { if (!marker) { setMarker(new google.maps.Marker({ position: { lat: 0, lng: 0, }, })); } // remove marker from map on unmount return () => { if (marker) { marker.setMap(null); } }; }, [marker]); useEffect(() => { if (marker) { marker.setOptions(options); } }, [marker, options]); useEffect(() => { if (marker) { [\"dragend\"].forEach((eventName) => google.maps.event.clearListeners(marker, eventName) ); marker.setOptions(options); if (dragend) { //map.addListener(\"click\", onClick); marker.addListener(\"dragend\", dragend); } } }, [marker, dragend, options]); return null; }; const deepCompareEqualsForMaps = createCustomEqual( (deepEqual) => (a: any, b: any) => { if ( isLatLngLiteral(a) || a instanceof google.maps.LatLng || isLatLngLiteral(b) || b instanceof google.maps.LatLng ) { return new google.maps.LatLng(a).equals(new google.maps.LatLng(b)); } // TODO extend to other types // use fast-equals for other objects return deepEqual(a, b); } ); function useDeepCompareMemoize(value: any) { const ref = useRef(); if (!deepCompareEqualsForMaps(value, ref.current)) { ref.current = value; } return ref.current; } function useDeepCompareEffectForMaps( callback: React.EffectCallback, dependencies: any[] ) { useEffect(callback, dependencies.map(useDeepCompareMemoize)); } export default LocationMap;
标签: reactjs typescript google-maps