Genel bakış
Bu eğiticide, @googlemaps/react-wrapper ile bir React uygulamasına Harita ve İşaretçi eklemeyi, harita ve işaretçileri uygulama durumuna entegre etmeyi öğrenebilirsiniz.
@googlemaps/react-wrapper uygulamasını yükleyin
Bileşen oluşturulduğunda Maps JavaScript API'yi dinamik olarak yüklemek için @googlemaps/react-wrapper kitaplığını yükleyin ve kullanın.
npm install @googlemaps/react-wrapper
Bu kitaplık içe aktarılabilir ve aşağıdakilerle kullanılabilir.
import { Wrapper, Status } from "@googlemaps/react-wrapper";
Bu bileşenin temel kullanımı, Maps JavaScript API'ye bağlı olan alt bileşenleri sarmalamaktır. Wrapper
bileşeni, yükleme bileşenlerini oluşturmak veya Maps JavaScript API'yi yüklerken hataları ele almak için kullanılan bir render
özelliğini de kabul eder.
const render = (status: Status) => {
return <h1>{status}</h1>;
};
<Wrapper apiKey={"YOUR_API_KEY"} render={render}>
<YourComponent/>
</Wrapper>
Harita bileşeni ekleme
Harita oluşturmak için temel bir işlevde büyük olasılıkla useRef
, useState
ve useEffect
Tepki kancaları kullanılır.
İlk harita bileşeninde aşağıdaki imza bulunur.
const Map: React.FC<{}> = () => {};
google.maps.Map
, oluşturucu parametresi olarak Element
gerektirdiğinden bileşenin kullanım ömrü boyunca değişmeyecek, değişmeyen bir nesnenin korunması için useRef gereklidir. Aşağıdaki snippet, Map
bileşeninin gövdesinde useEffect kancasındaki bir haritayı somutlaştırır.
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]);
JavaScript
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]);
Yukarıdaki useEffect
kancası yalnızca ref
değiştiğinde çalışır. Map
bileşeni artık aşağıdakileri döndürür.
return <div ref={ref} />
Ek bileşeni olan harita bileşenini genişlet
Temel harita bileşeni; harita seçenekleri, etkinlik işleyiciler ve haritayı içeren div'e uygulanan stiller için ek sahneler ile genişletilebilir. Aşağıdaki kod, bu işlevsel bileşenin genişletilmiş arayüzünü göstermektedir.
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
nesnesi doğrudan iletilebilir ve oluşturulan div
üzerinde bir özellik olarak ayarlanabilir.
return <div ref={ref} style={style} />;
onClick
, onIdle
ve google.maps.MapOptions
, güncellemeleri zorunlu olarak google.maps.Map
için uygulamak üzere useEffect
kanca gerektirir.
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]);
JavaScript
// 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]);
Ürün olarak iletilen bir işleyici güncellendiğinde mevcut dinleyicileri temizlemek için etkinlik dinleyicileri biraz daha karmaşık koda ihtiyaç duyar.
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]);
JavaScript
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]);
İşaretçi bileşeni oluşturma
İşaretçi bileşeni, useEffect
ve useState
kancalarına sahip harita bileşeniyle benzer kalıpları kullanır.
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; };
JavaScript
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; };
google.maps.Map
, DOM manipülasyonunu yönettiği için bileşen null döndürür.
İşaretçileri haritanın alt bileşeni olarak ekleme
İşaretçileri bir haritaya eklemek için Marker
bileşeni, aşağıdaki gibi özel children
donanımı kullanılarak Map
bileşenine iletilir.
<Wrapper apiKey={"YOUR_API_KEY"}>
<Map center={center} zoom={zoom}>
<Marker position={position} />
</Map>
</Wrapper>
google.maps.Map
nesnesinin tüm alt öğelere ek bir özellik olarak iletilmesi için Map
bileşeninin çıkışında küçük bir değişiklik yapılması gerekir.
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 }); } })} </> );
JavaScript
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 }); } })} </> );
Bağlantı haritası ve uygulama durumu
Uygulama, onClick
ve onIdle
geri çağırmaları için yukarıdaki deseni kullanarak, haritayı tıklama veya kaydırma gibi kullanıcı işlemlerini tam olarak entegre etmek üzere genişletilebilir.
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()); };
JavaScript
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()); };
Bu kancalar, enlem girişinde gösterildiği gibi aşağıdaki desen kullanılarak form öğelerine entegre edilebilir.
<label htmlFor="lat">Latitude</label>
<input
type="number"
id="lat"
name="lat"
value={center.lat}
onChange={(event) =>
setCenter({ ...center, lat: Number(event.target.value) })
}
/>
Son olarak uygulama, tıklamaları izler ve her tıklama konumunda işaretçiler oluşturur. Aşağıdaki kod, tıklama etkinliğinden LatLng
değerini iletmek için position
değişkenini kullanır.
{clicks.map((latLng, i) => (<Marker key={i} position={latLng} />))}
Kodu keşfedin
Örnek kodun tamamı, aşağıdaki online kod oyun alanları aracılığıyla veya git deposunu klonlanarak bulunabilir.
Örneği Deneyin
Örneği Klonla
Bu örneği yerel olarak çalıştırmak için Git ve Node.js gereklidir. Node.js ve NPM'yi yüklemek için bu talimatları uygulayın. Aşağıdaki komutlar klonlanır, bağımlıları yükleyin ve örnek uygulamayı başlatın.
git clone -b sample-react-map https://github.com/googlemaps/js-samples.git
cd js-samples
npm i
npm start
Diğer örnekler, sample-SAMPLE_NAME
ile başlayan herhangi bir dala geçiş yapılarak denenebilir.
git checkout sample-SAMPLE_NAME
npm i
npm start