प्रतिक्रिया वाले ऐप्लिकेशन में मैप और मार्कर जोड़ना

खास जानकारी

यह ट्यूटोरियल आपको @googlemaps/react-wrapper का इस्तेमाल करके मैप और मार्कर को प्रतिक्रिया ऐप्लिकेशन में जोड़ने और ऐप्लिकेशन की स्थिति में मैप और मार्कर को जोड़ने का तरीका दिखाता है.

@googlemaps/react-wrapper इंस्टॉल करना

कॉम्पोनेंट के रेंडर होने पर Maps JavaScript एपीआई को डाइनैमिक तरीके से लोड करने के लिए, @googlemaps/react-wrapper लाइब्रेरी को इंस्टॉल करें और उसका इस्तेमाल करें.

npm install @googlemaps/react-wrapper

इस लाइब्रेरी को इंपोर्ट करके, इनके साथ इस्तेमाल किया जा सकता है.

import { Wrapper, Status } from "@googlemaps/react-wrapper";

इस कॉम्पोनेंट का बुनियादी इस्तेमाल, चाइल्ड कॉम्पोनेंट को रैप करना है जो Maps JavaScript एपीआई पर निर्भर करते हैं. Wrapper कॉम्पोनेंट, लोड होने वाले कॉम्पोनेंट को रेंडर करने या Maps JavaScript API को लोड करने में होने वाली गड़बड़ियों को ठीक करने के लिए, render प्रॉप का इस्तेमाल भी करता है.

const render = (status: Status) => {
  return <h1>{status}</h1>;
};

<Wrapper apiKey={"YOUR_API_KEY"} render={render}>
  <YourComponent/>
</Wrapper>

मैप कॉम्पोनेंट जोड़ें

मैप को रेंडर करने के लिए बुनियादी फ़ंक्शनल कॉम्पोनेंट, useRef, useState, और useEffect रिएक्ट हुक का इस्तेमाल कर सकता है.

शुरुआती मैप कॉम्पोनेंट में नीचे दिया गया हस्ताक्षर होगा.

const Map: React.FC<{}> = () => {};

google.maps.Map को कंस्ट्रक्टर पैरामीटर के तौर पर Element की ज़रूरत होती है. इसलिए, बदले जा सकने वाले ऐसे ऑब्जेक्ट का रखरखाव करने के लिए, useRef की ज़रूरत होती है जो कॉम्पोनेंट के लाइफ़टाइम में बना रहेगा. यह स्निपेट, Map कॉम्पोनेंट के मुख्य हिस्से में useImpact हुक में मैप को इंस्टैंशिएट करता है.

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]);

ऊपर दिया गया 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 के लिए, google.maps.Map हुक को useEffect पर लागू करना ज़रूरी है.

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]);

जब इवेंट हैंडलर किसी प्रॉप के रूप में पास हो जाता है, तो मौजूदा लिसनर को साफ़ करने के लिए इवेंट लिसनर को थोड़ा और जटिल कोड की ज़रूरत होती है.

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]);

मार्कर कॉम्पोनेंट बनाना

मार्कर कॉम्पोनेंट, 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;
};

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 फेरबदल को मैनेज करता है. ऐसा होने पर, कॉम्पोनेंट शून्य दिखता है.

मैप के चाइल्ड कॉम्पोनेंट के तौर पर मार्कर जोड़ें

किसी नक्शे में मार्कर जोड़ने के लिए, Marker घटक को निम्न तरीके से विशेष children प्रोप का उपयोग करके Map घटक को पास किया जाएगा.

<Wrapper apiKey={"YOUR_API_KEY"}>
  <Map center={center} zoom={zoom}>
    <Marker position={position} />
  </Map>
</Wrapper>

सभी कॉम्पोनेंट को अतिरिक्त प्रॉपर्टी के तौर पर, google.maps.Map ऑब्जेक्ट देने के लिए, 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 });
      }
    })}
  </>
);

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 });
      }
    })}
  </>
);

लिंक मैप और ऐप्लिकेशन स्थिति

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());
};

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());
};

इन हुक को नीचे दिए गए पैटर्न का इस्तेमाल करके, फ़ॉर्म के इनपुट में इंटिग्रेट किया जा सकता है, जैसा कि अक्षांश इनपुट के साथ दिखाया गया है.

<label htmlFor="lat">Latitude</label>
<input
  type="number"
  id="lat"
  name="lat"
  value={center.lat}
  onChange={(event) =>
    setCenter({ ...center, lat: Number(event.target.value) })
  }
/>

आखिर में, ऐप्लिकेशन क्लिक को ट्रैक करता है और यह हर क्लिक की जगह पर मार्कर रेंडर करता है. यह कोड क्लिक इवेंट से LatLng वैल्यू को पास करने के लिए, position वैरिएबल का इस्तेमाल करता है.

{clicks.map((latLng, i) => (<Marker key={i} position={latLng} />))}

कोड एक्सप्लोर करें

पूरे सैंपल कोड के बारे में जानने के लिए नीचे दिए गए ऑनलाइन कोड प्लेग्राउंड पर जाएं. इसके अलावा, Git डेटा को स्टोर करने की जगह को क्लोन करके देखें.

सैंपल आज़माएं

सैंपल का नमूना

इस नमूने को स्थानीय रूप से चलाने के लिए, 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