بررسی اجمالی
این آموزش به شما نشان می دهد که چگونه با استفاده از @googlemaps/react-wrapper یک نقشه و نشانگر را به برنامه React اضافه کنید و نقشه و نشانگرها را در وضعیت برنامه ادغام کنید.
@googlemaps/react-wrapper را نصب کنید
کتابخانه @googlemaps/react-wrapper را برای بارگیری پویا Maps JavaScript API هنگام رندر شدن مؤلفه نصب و استفاده کنید.
npm install @googlemaps/react-wrapper
این کتابخانه با موارد زیر قابل واردات و استفاده است.
import { Wrapper, Status } from "@googlemaps/react-wrapper";
کاربرد اصلی این مؤلفه، بسته بندی مؤلفه های فرزند است که به Maps JavaScript API وابسته هستند. کامپوننت Wrapper
همچنین یک پایه render
برای رندر کردن مولفههای بارگیری یا رسیدگی به خطاها در بارگیری Maps JavaScript API میپذیرد.
const render = (status: Status) => {
return <h1>{status}</h1>;
};
<Wrapper apiKey={"YOUR_API_KEY"} render={render}>
<YourComponent/>
</Wrapper>
یک جزء نقشه اضافه کنید
یک مؤلفه کاربردی اصلی برای ارائه نقشه احتمالاً از قلاب های useRef
، useState
و useEffect
React استفاده می کند.
مولفه نقشه اولیه دارای امضای زیر خواهد بود.
const Map: React.FC<{}> = () => {};
از آنجایی که google.maps.Map
به Element
به عنوان پارامتر سازنده نیاز دارد، userRef برای حفظ یک شیء قابل تغییر که در طول عمر جزء باقی بماند، مورد نیاز است. قطعه زیر یک نقشه را در قلاب useEffect در بدنه مؤلفه Map
نشان می دهد.
TypeScript
const ref = React.useRef<HTMLDivElement>(null); const [map, setMap] = React.useState<google.maps.Map>(); React.useEffect(() => { if (ref.current && !map) { setMap(new window.google.maps.Map(ref.current, {})); } }, [ref, map]);
جاوا اسکریپت
const ref = React.useRef(null); const [map, setMap] = React.useState(); React.useEffect(() => { if (ref.current && !map) { setMap(new window.google.maps.Map(ref.current, {})); } }, [ref, map]);
قلاب useEffect
بالا فقط زمانی اجرا می شود که ref
تغییر کرده باشد. مؤلفه Map
اکنون موارد زیر را برمی گرداند.
return <div ref={ref} />
مولفه نقشه را با لوازم اضافی گسترش دهید
مؤلفه اصلی نقشه را می توان با لوازم اضافی برای گزینه های نقشه، شنوندگان رویداد و سبک های اعمال شده در div حاوی نقشه گسترش داد. کد زیر رابط توسعه یافته این مؤلفه کاربردی را نشان می دهد.
interface MapProps extends google.maps.MapOptions {
style: { [key: string]: string };
onClick?: (e: google.maps.MapMouseEvent) => void;
onIdle?: (map: google.maps.Map) => void;
}
const Map: React.FC<MapProps> = ({
onClick,
onIdle,
children,
style,
...options
}) => {}
شیء style
میتواند مستقیماً از آن عبور کرده و بهعنوان یک پایه روی div
رندر شده تنظیم شود.
return <div ref={ref} style={style} />;
onClick
، onIdle
، و google.maps.MapOptions
به قلاب های useEffect
نیاز دارند تا به طور ضروری به روز رسانی ها را در google.maps.Map
اعمال کنند.
TypeScript
// 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]);
جاوا اسکریپت
// 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]);
شنوندگان رویداد به کد کمی پیچیدهتر نیاز دارند تا شنوندههای موجود را هنگامی که کنترلکنندهای که بهعنوان پایه بهروزرسانی میشود، پاک کنند.
TypeScript
React.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]);
جاوا اسکریپت
React.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]);
یک جزء نشانگر بسازید
مؤلفه نشانگر از الگوهای مشابه به عنوان مؤلفه نقشه با قلاب های useEffect
و useState
استفاده می کند.
TypeScript
const Marker: React.FC<google.maps.MarkerOptions> = (options) => { const [marker, setMarker] = React.useState<google.maps.Marker>(); React.useEffect(() => { if (!marker) { setMarker(new google.maps.Marker()); } // remove marker from map on unmount return () => { if (marker) { marker.setMap(null); } }; }, [marker]); React.useEffect(() => { if (marker) { marker.setOptions(options); } }, [marker, options]); return null; };
جاوا اسکریپت
const Marker = (options) => { const [marker, setMarker] = React.useState(); React.useEffect(() => { if (!marker) { setMarker(new google.maps.Marker()); } // remove marker from map on unmount return () => { if (marker) { marker.setMap(null); } }; }, [marker]); React.useEffect(() => { if (marker) { marker.setOptions(options); } }, [marker, options]); return null; };
جزء null برمیگرداند زیرا google.maps.Map
دستکاری DOM را مدیریت میکند.
نشانگرها را به عنوان جزء فرزند نقشه اضافه کنید
برای افزودن نشانگرها به یک نقشه، مولفه Marker
با استفاده از پایه ویژه children
مانند زیر به مؤلفه Map
منتقل می شود.
<Wrapper apiKey={"YOUR_API_KEY"}>
<Map center={center} zoom={zoom}>
<Marker position={position} />
</Map>
</Wrapper>
یک تغییر کوچک در خروجی مولفه Map
باید ایجاد شود تا شی google.maps.Map
به عنوان یک وسیله اضافی به همه کودکان ارسال شود.
TypeScript
return ( <> <div ref={ref} style={style} /> {React.Children.map(children, (child) => { if (React.isValidElement(child)) { // set the map prop on the child component // @ts-ignore return React.cloneElement(child, { map }); } })} </> );
جاوا اسکریپت
return ( <> <div ref={ref} style={style} /> {React.Children.map(children, (child) => { if (React.isValidElement(child)) { // set the map prop on the child component // @ts-ignore return React.cloneElement(child, { map }); } })} </> );
پیوند نقشه و وضعیت برنامه
با استفاده از الگوی بالا برای تماسهای onClick
و onIdle
، برنامه را میتوان برای ادغام کامل اقدامات کاربر مانند کلیک کردن یا حرکت در نقشه گسترش داد.
TypeScript
const [clicks, setClicks] = React.useState<google.maps.LatLng[]>([]); const [zoom, setZoom] = React.useState(3); // initial zoom const [center, setCenter] = React.useState<google.maps.LatLngLiteral>({ lat: 0, lng: 0, }); const onClick = (e: google.maps.MapMouseEvent) => { // avoid directly mutating state setClicks([...clicks, e.latLng!]); }; const onIdle = (m: google.maps.Map) => { console.log("onIdle"); setZoom(m.getZoom()!); setCenter(m.getCenter()!.toJSON()); };
جاوا اسکریپت
const [clicks, setClicks] = React.useState([]); const [zoom, setZoom] = React.useState(3); // initial zoom const [center, setCenter] = React.useState({ lat: 0, lng: 0, }); const onClick = (e) => { // avoid directly mutating state setClicks([...clicks, e.latLng]); }; const onIdle = (m) => { console.log("onIdle"); setZoom(m.getZoom()); setCenter(m.getCenter().toJSON()); };
این قلاب ها را می توان با استفاده از الگوی زیر که با ورودی عرض جغرافیایی نشان داده شده است، در عناصر فرم ادغام کرد.
<label htmlFor="lat">Latitude</label>
<input
type="number"
id="lat"
name="lat"
value={center.lat}
onChange={(event) =>
setCenter({ ...center, lat: Number(event.target.value) })
}
/>
در نهایت، برنامه کلیک ها را ردیابی می کند و نشانگرها را در هر مکان کلیک نشان می دهد. کد زیر از متغیر position
برای ارسال مقدار LatLng
از رویداد کلیک استفاده می کند.
{clicks.map((latLng, i) => (<Marker key={i} position={latLng} />))}
کد را کاوش کنید
کد نمونه کامل را می توان از طریق زمین های بازی کد آنلاین زیر یا با شبیه سازی مخزن git کاوش کرد.
Sample را امتحان کنید
کلون نمونه
Git و Node.js برای اجرای این نمونه به صورت محلی مورد نیاز هستند. این دستورالعمل ها را برای نصب Node.js و NPM دنبال کنید. دستورات زیر وابستگی ها را شبیه سازی کرده، نصب کرده و نمونه برنامه را شروع می کنند.
git clone -b sample-react-map https://github.com/googlemaps/js-samples.git
cd js-samples
npm i
npm start
نمونه های دیگر را می توان با جابجایی به هر شاخه ای که با sample- SAMPLE_NAME
شروع می شود امتحان کرد.
git checkout sample-SAMPLE_NAME
npm i
npm start