首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Reactjs将函数实例传递给子支柱

Reactjs将函数实例传递给子支柱
EN

Stack Overflow用户
提问于 2022-08-18 07:07:36
回答 1查看 48关注 0票数 1

我有三个组成部分。<DroppointMap /><Map /><MapMarker /> --我构建了符合@googlemaps/react-wrapper规范的组件,并安装了@types/google.maps。使用以下文档:https://developers.google.com/maps/documentation/javascript/react-map

我希望能够使用fitBounds()函数,根据我描述的{lat: 0.0, lng: 0.0}标记集将地图放大到给定的区域。在用函数useCallback()扩展边界之后,我尝试制作一个返回函数google.maps.LatLngBounds()extend()钩子。

代码语言:javascript
复制
const bounds = useCallback(() => {
  const latLngBounds = new google.maps.LatLngBounds();

  droppoints.forEach((droppoint) => {
    latLngBounds.extend(
      new google.maps.LatLng(
        droppoint.coordinates.latitude,
        droppoint.coordinates.longitude
      )
    );
  });

  return latLngBounds;
}, [droppoints]);

在我的<Map />中,我指定了我的bounds?: google.maps.LatLngBounds属性,在运行我的应用程序之前,我没有看到任何来自react/ts/eslint或其他方面的抱怨,该应用程序告诉我,DroppointMap/bounds中的google is not defined对我来说几乎没有任何意义。

下面列出了这些组件(<MapMarker />在这一点上是相关的)。

droppoint-map.tsx

代码语言:javascript
复制
import { IGoogleCredentials } from '../../context';
import { googleMapsContainer } from './droppoint-map.css';
import { ReactElement, useCallback, useMemo, useState } from 'react';
import { Status, Wrapper } from '@googlemaps/react-wrapper';
import { Map } from './map';
import { MapMarker } from './map-marker';
import { IApiServicepoint } from '../../use-droppoints/types';

export interface IDroppointMapProps {
    googleCredentials: IGoogleCredentials;
    droppoints: IApiServicepoint[];
}

export function DroppointMap({ googleCredentials, droppoints }: IDroppointMapProps) {
    const render = useCallback((status: Status): ReactElement => {
        if (status === Status.LOADING) return <h3>{status} ..</h3>;
        if (status === Status.FAILURE) return <h3>{status} ...</h3>;
        return <></>;
    }, []);

    const [center, setCenter] = useState({ lat: 0, lng: 0 });
    const [zoom, setZoom] = useState(9);

    // omitted for readability
    const mapOptions: google.maps.MapOptions = useMemo();

    const bounds = useCallback(() => {
        const latLngBounds = new google.maps.LatLngBounds();

        droppoints.forEach((droppoint) => {
            latLngBounds.extend(
                new google.maps.LatLng(
                    droppoint.coordinates.latitude,
                    droppoint.coordinates.longitude
                )
            );
        });

        return latLngBounds;
    }, [droppoints]);

    return (
        <Wrapper apiKey={googleCredentials.googleMapsApiKey} render={render}>
            <Map
                center={center}
                zoom={zoom}
                className={googleMapsContainer}
                options={mapOptions}
                bounds={bounds()}
            >
                {droppoints.map((droppoint, index) => {
                    return (
                        <MapMarker
                            position={{
                                lat: droppoint.coordinates.latitude,
                                lng: droppoint.coordinates.longitude
                            }}
                            key={index}
                        />
                    );
                })}
            </Map>
        </Wrapper>
    );
}

map.tsx

代码语言:javascript
复制
import {
    Children,
    cloneElement,
    isValidElement,
    PropsWithChildren,
    ReactNode,
    useEffect,
    useRef,
    useState
} from 'react';

export interface IMapProps extends google.maps.MapOptions {
    center: google.maps.LatLngLiteral;
    zoom: number;
    className?: string;
    children?: ReactNode;
    options?: google.maps.MapOptions;
    bounds?: google.maps.LatLngBounds;
}

export function Map({
    center,
    zoom,
    className,
    children,
    options,
    bounds
}: PropsWithChildren<IMapProps>) {
    const ref = useRef<HTMLDivElement>(null);
    const [map, setMap] = useState<google.maps.Map>();

    useEffect(() => {
        // eslint-disable-next-line no-new
        setMap(new window.google.maps.Map(ref.current!, { ...options }));
    }, [options]);

    if (map) {
        map.setCenter(center);
        map.setZoom(zoom);
        if (bounds) {
            map.fitBounds(bounds);
        }
    }

    return (
        <div className={className} ref={ref} id="map">
            {Children.map(children, (child) => {
                if (isValidElement(child)) {
                    return cloneElement(child, { map });
                }
            })}
        </div>
    );
}
EN

回答 1

Stack Overflow用户

发布于 2022-10-20 23:06:04

您只需将droppoints传递给Map组件并使用它们来适应边界:

代码语言:javascript
复制
  const bounds = new google.maps.LatLngBounds();
  droppoints.forEach((droppoint) => {
    const point = { lat: droppoint.coordinates.latitude, lng: droppoint.coordinates.longitude };
    bounds.extend(point);
  });
  map.fitBounds(bounds);

还可以选择更新地图的中心:

代码语言:javascript
复制
  map.setCenter(bounds.getCenter());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73398729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档