ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React์—์„œ TMap API ์‚ฌ์šฉํ•˜๊ธฐ
    TECH 2023. 12. 30. 14:48

    ์ด ๊ธ€์—์„œ๋Š” ๋„ค์ด๋ฒ„ ๋ถ€์ŠคํŠธ์บ ํ”„ ๋‚ด์˜ ๋ชจ๊ฐ์ฝ” ๋ชจ์ง‘/๊ด€๋ฆฌ ํ”Œ๋žซํผ์ธ ๋ชจ๋ฝ ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๋ฉฐ TMap API๋ฅผ ์‚ฌ์šฉํ–ˆ๋˜ ํ›„๊ธฐ๋ฅผ ๋‹ด์•„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. 

     

    GitHub - boostcampwm2023/web17_morak: Morak | ๋„ค์ด๋ฒ„ ๋ถ€์ŠคํŠธ์บ ํ”„ ๋‚ด ๋ชจ๊ฐ์ฝ” ๋ชจ์ง‘/๊ด€๋ฆฌ ํ”Œ๋žซํผ ๐Ÿง‘๐Ÿป‍๐Ÿ’ป

    Morak | ๋„ค์ด๋ฒ„ ๋ถ€์ŠคํŠธ์บ ํ”„ ๋‚ด ๋ชจ๊ฐ์ฝ” ๋ชจ์ง‘/๊ด€๋ฆฌ ํ”Œ๋žซํผ ๐Ÿง‘๐Ÿป‍๐Ÿ’ป๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป๐Ÿ‘จ๐Ÿป‍๐Ÿ’ป. Contribute to boostcampwm2023/web17_morak development by creating an account on GitHub.

    github.com

     
     
    TMAP Open API๋Š” ์›น ๊ฐœ๋ฐœ ๋˜๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ๋‹ค์–‘ํ•˜๊ฒŒ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก, Javascript ํ˜•ํƒœ๋กœ ์ œ๊ณต๋˜๋Š” TMAP ์ง€๋„ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค. TMap API๋Š” ์ด๋ฏธ์ง€๋กœ ์ง€๋„๋ฅผ ๊ทธ๋ฆฌ๋Š” Raster Map(V2)๊ณผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ง€๋„๋ฅผ ๊ทธ๋ฆฌ๋Š” Vector Map(V3) ๋‘ ๊ฐ€์ง€๋ฅผ ์ง€์›ํ•˜๋ฉฐ Vector Map์€ ํ™•๋Œ€/์ถ•์†Œ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ํšŒ์ „ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ์ฐจ์ด์ ์ด ์žˆ๋‹ค๊ณ  ํ•˜๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ์‚ฌ์šฉํ•ด ๋ณด์•˜์„ ๋•Œ๋Š” ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์€ Raster Map์ด ๋” ๋งŽ์•˜์Šต๋‹ˆ๋‹ค.
     
    ๋˜ํ•œ, ์ด ๊ธ€์—์„œ ์„ค๋ช…ํ•˜๋Š” ๋ฐฉ์‹์€ Raster Map ๋ฐฉ์‹์ธ TMapv2๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. TMapv3์— ์ ์šฉํ•  ๋•Œ๋Š” ๋ฉ”์†Œ๋“œ๋ช…์ด๋‚˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์œผ๋‹ˆ, ์ž์„ธํ•œ ์‚ฌํ•ญ์€ TMap์˜ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.
     
     
     
     

    ๊ธฐ๋Šฅ ์„ค๋ช…

    ๋ชจ๋ฝ์—์„œ๋Š” ๋ชจ๊ฐ์ฝ”๋ฅผ ์ฃผ์ตœํ•  ๊ฒฝ์šฐ ํผ์„ ์ž‘์„ฑํ•˜์—ฌ ๊ธ€์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ํผ ์ž‘์„ฑ ์‹œ ์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์„ ๋‹จ์ˆœ ํ…์ŠคํŠธ๊ฐ€ ์•„๋‹Œ ์ฃผ์†Œ ํ˜•์‹์˜ ํ…์ŠคํŠธ๋กœ ์ž…๋ ฅ๋ฐ›๊ธฐ ์œ„ํ•ด TMap API๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
     
     
     

     

    ์ง€๋„ ๋„์šฐ๊ธฐ

    import { useEffect, useState } from 'react';
    
    import { TMap } from '@/types';
    
    const { Tmapv2 } = window;
    
    export const useMap = (mapRef: React.RefObject<HTMLDivElement>) => {
      const [mapInstance, setMapInstance] = useState<TMap | null>(null);
    
      useEffect(() => {
        if (mapRef.current?.firstChild || mapInstance) {
          return;
        }
    
        const map = new Tmapv2.Map('map', {
          zoom: DEFAULT_ZOOM_LEVEL,
          zoomControl: false,
          center: new Tmapv2.LatLng(INITIAL_LATITUDE, INITIAL_LONGITUDE),
        });
    
        map.setZoomLimit(MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL);
        setMapInstance(map);
      }, [mapRef, mapInstance]);
    
    };

     
     

    ์šฐ์„  ์ง€๋„๋Š” ๋ Œ๋”๋งํ•  ๊ฒƒ ํ•˜๋‚˜๋งŒ ๋„์šฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ง€๋„๋ฅผ ๋„์šฐ๊ธฐ ์œ„ํ•œ useMap ํ›…์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

     

    useMap์˜ ์ธ์ž์ธ mapRef๋Š” ์„ค์ •ํ•œ ์ง€๋„์™€ div ํƒœ๊ทธ๋ฅผ ์—ฐ๊ฒฐํ•ด ์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. 

     

    ๋˜ํ•œ ์ดํ›„์— new Tmapv2.Map๋กœ ์ƒ์„ฑํ•œ map ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜์—ฌ ์ง€๋„๋ฅผ ์กฐ์ž‘ํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๋ฅผ ์œ„ํ•ด mapInstance state๋ฅผ ๋งŒ๋“ค์–ด ์ €์žฅํ•ด ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

     

    useEffect ๋‚ด์˜ if ๋ฌธ์—์„œ mapRef.current?.firstChild์™€ mapInstance๋ฅผ ๊ฒ€์‚ฌํ•œ ์ด์œ ๋Š”, ์ง€๋„ ๊ฐ์ฒด๊ฐ€ ๋‘ ๊ฐœ ์ƒ์„ฑ๋˜๋Š” ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ ํฌ์ŠคํŒ…์„ ์ฐธ๊ณ ํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

     
     

    ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ชจ๋‹ฌ์— ์ง€๋„๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
     

     

     
     

    ๊ฒ€์ƒ‰์–ด๋กœ ์žฅ์†Œ ์„ ํƒํ•˜๋ฉด ์ง€๋„์— ํ•€์œผ๋กœ ๋ณด์—ฌ ์ฃผ๊ธฐ

    ์žฅ์†Œ ๋ชจ๋‹ฌ์˜ ์™ผ์ชฝ ์ƒ๋‹จ์˜ ์ธํ’‹์— ์žฅ์†Œ ํ‚ค์›Œ๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ๋ฆฌ์ŠคํŠธ ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅ๋˜๋ฉฐ, ๋ฆฌ์ŠคํŠธ ๋‚ด์˜ ์•„์ดํ…œ์„ ํด๋ฆญํ•˜๋ฉด ์žฅ์†Œ๊ฐ€ ์„ ํƒ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์—๊ฒŒ ์„ ํƒํ•œ ์žฅ์†Œ๋ฅผ ์ง€๋„ ๋‚ด์—์„œ๋„ ๋ณด์—ฌ ์ฃผ๊ธฐ ์œ„ํ•ด ํ•€์œผ๋กœ ํ‘œ์‹œํ•ด ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
     
     

    import { useCallback, useEffect, useState } from 'react';
    
    import { Marker } from '@/components/Map/Marker';
    import { TMap, TMapMarker } from '@/types';
    
    const { Tmapv2 } = window;
    
    export const useMap = (mapRef: React.RefObject<HTMLDivElement>) => {
      const [mapInstance, setMapInstance] = useState<TMap | null>(null);
      const [currentMarker, setCurrentMarker] = useState<TMapMarker | null>(null);
    
      // ์ง€๋„ ๋„์šฐ๋Š” ์ฝ”๋“œ ์ƒ๋žต
    
      const updateMarker = useCallback(
        (coord: { latitude: number | null; longitude: number | null }) => {
          const { latitude, longitude } = coord;
          if (!(latitude && longitude) || !mapInstance) {
            return;
          }
    
          if (currentMarker) {
            const { _lat: prevLatitude, _lng: prevLongitude } =
              currentMarker.getPosition();
            if (prevLatitude === latitude && prevLongitude === longitude) {
              return;
            }
          }
    
          currentMarker?.setMap(null);
          const position = new Tmapv2.LatLng(latitude, longitude);
          const marker = new Tmapv2.Marker({
            position,
            map: mapInstance,
            icon: markerIcon,
            iconSize: new Tmapv2.Size(50, 50),
          })
          
          setCurrentMarker(marker);
          mapInstance?.setCenter(position);
        },
        [mapInstance, currentMarker],
      );
    
      return { mapInstance, updateMarker };
    };

     

    ์šฐ์„  useMap ํ›…์—์„œ ์žฅ์†Œ์˜ ์„ ํƒ์— ๋”ฐ๋ผ ์ง€๋„์— ๋งˆ์ปค๋ฅผ ์ฐ์–ด ์ฃผ๋Š” updateMarker๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

     

    updateMarker์—์„œ๋Š” ์ธ์ž๋กœ ๋ฐ›์€ coord์˜ ์œ„๋„/๊ฒฝ๋„์™€ ์ด๋ฏธ ์ฐํ˜€์ ธ ์žˆ๋Š” marker์˜ ์œ„๋„/๊ฒฝ๋„ ๊ฐ’์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

     

    ์ธ์ž๋กœ ๋ฐ›์€ coord๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š๊ฑฐ๋‚˜, coord๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด updateMarker๋Š” ๋งˆ์ปค์˜ ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋กœ์ง์„ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

     

    ๋งŒ์ผ coord์˜ ์œ„๋„/๊ฒฝ๋„๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๋ฉด, currentMarker.setMap(null)๋กœ ๋งˆ์ปค๋ฅผ ์ง€๋„์—์„œ ์ง€์šฐ๊ณ  ์ƒˆ๋กœ์šด ์ปค์Šคํ…€ ๋งˆ์ปค๋ฅผ ์ง€๋„์— ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค. 

    ๊ทธ๋ฆฌ๊ณ  mapInstance.setCenter(position)์œผ๋กœ ์ƒˆ๋กœ ์ฐ์€ ๋งˆ์ปค๊ฐ€ ์ง€๋„ ์ค‘์•™์— ํ‘œ์‹œ๋˜๋„๋ก ๋ณด์—ฌ ์ค๋‹ˆ๋‹ค.

     

    TMapLatLng์™€ ๊ฐ™์€ ํƒ€์ž…์€ TMap API Guide๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

     
     

    ๊ทธ๋ฆฌ๊ณ  ๋งต ๋ชจ๋‹ฌ์—์„œ๋Š” useMap ํ›…์˜ updateMarker ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

    ์šฐ์„  ์žฅ์†Œ ๋ฆฌ์ŠคํŠธ ์ค‘ ํ•˜๋‚˜์˜ ์žฅ์†Œ๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•ด ํด๋ฆญํ•˜๋ฉด onClickAddressListItem ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋Š” coord์— ์„ ํƒํ•œ ์žฅ์†Œ์˜ ์œ„๋„์™€ ๊ฒฝ๋„๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

    import { useEffect, useRef, useState } from "react";
    import { useMap } from "./useMap";
    
    export function MapModal() {
      const [selectedAddress, setSelectedAddress] = useState("");
      const [coord, setCoord] = useState<{
        latitude: number | null;
        longitude: number | null;
      }>({
        latitude: null,
        longitude: null,
      });
      const mapRef = useRef<HTMLDivElement>(null);
      const { updateMarker } = useMap(mapRef);
    
      useEffect(() => {
        updateMarker(coord);
      }, [coord, updateMarker]);
    
      const onClickAddressListItem = <
        Event extends React.MouseEvent | React.KeyboardEvent,
      >(
        e: Event,
      ) => {
        setSelectedAddress(e.currentTarget.getAttribute("value") || "");
        const coordinate = {
          latitude: Number(e.currentTarget.getAttribute("data-lat")),
          longitude: Number(e.currentTarget.getAttribute("data-lon")),
        };
    
        setCoord(coordinate);
      };
    
      return (
       // ์ƒ๋žต
      );
    }

     

    ๊ทธ๋ฆฌ๊ณ  coord๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๋ฉด, updateMarker๋ฅผ ํ˜ธ์ถœํ•ด ์ง€๋„์˜ ๋งˆ์ปค๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

     
     

     
    ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์žฅ์†Œ ๋ฆฌ์ŠคํŠธ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ง€๋„์˜ ๋งˆ์ปค๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
     
     
     
     

    ์ง€๋„ ํด๋ฆญ ์‹œ ๋งˆ์ปค ๋„์šฐ๊ธฐ

    ์žฅ์†Œ๋ฅผ ํ…์ŠคํŠธ๋กœ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ์ง€๋„๋ฅผ ํด๋ฆญํ•˜์—ฌ ์›ํ•˜๋Š” ์žฅ์†Œ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.
     

     
     
     
     
    T Map ํด๋ฆญํ•œ ์œ„์น˜์— ๋งˆ์ปค ํ‘œ์‹œํ•˜๊ธฐ ์˜ˆ์‹œ์— ๋‚˜์˜จ ๋Œ€๋กœ ๊ตฌํ˜„์„ ์‹œ๋„ํ–ˆ์œผ๋‚˜, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งˆ์ปค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ ์ฐํžˆ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
     

     

    ๋”ฐ๋ผ์„œ ์˜ˆ์‹œ์™€ ๊ฐ™์€ ๋ฐฉ์‹์ด ์•„๋‹Œ currentMarker๋กœ ๋งˆ์ปค๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ๋งˆ์ปค์˜ position์„ ๋ฐ”๊พธ์–ด ์ƒˆ๋กœ์šด ์œ„์น˜์— ๋งˆ์ปค๋ฅผ ์ฐ์–ด ์ฃผ๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

     
     
    ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    import { useEffect, useState } from "react";
    
    import { Marker } from "@/components/Map/Marker";
    import { TMap, TMapMarker } from "@/types";
    
    const { Tmapv2 } = window;
    
    export const useMap = (mapRef: React.RefObject<HTMLDivElement>) => {
      const [mapInstance, setMapInstance] = useState<TMap | null>(null);
      const [currentMarker, setCurrentMarker] = useState<TMapMarker | null>(null);
    
      useEffect(() => {
        if (!mapInstance) {
          return;
        }
    
        mapInstance.addListener("Click", (e) => {
          const { latLng } = e;
          const position = new Tmapv2.LatLng(latLng.lat(), latLng.lng());
    
          if (!currentMarker) {
            const marker = new Tmapv2.Marker({
                position,
                map: mapInstance,
                icon: markerIcon,
                iconSize: new Tmapv2.Size(50, 50),
              })
            setCurrentMarker(marker);
          } else {
            currentMarker.setPosition(position);
          }
        });
      }, [mapInstance, currentMarker]);
    };

     

    ์—ฌ๊ธฐ์„œ currentMarker๊ฐ€ ์—†๋‹ค๋ฉด ์ƒˆ๋กœ์šด ๋งˆ์ปค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ setCurrentMarker์— ํ• ๋‹นํ•˜๊ณ , 

    currentMarker๊ฐ€ ์žˆ๋‹ค๋ฉด setPosition ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋งˆ์ปค์˜ ํฌ์ง€์…˜๋งŒ ๋ฐ”๊ฟ”์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

     
     
     
     
     
     
    ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ๋‚˜๋‹ˆ, ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ์— ์ง๋ฉดํ–ˆ์Šต๋‹ˆ๋‹ค. (๋ฒ„๊ทธ ์ณ‡๋ฐ”ํ€ด...)
    ์žฅ์†Œ ํด๋ฆญ ์‹œ ์ƒ๊ธฐ๋Š” ๋งˆ์ปค์™€ ์ง€๋„ ํด๋ฆญ ์‹œ ์ƒ๊ธฐ๋Š” ๋งˆ์ปค๊ฐ€ ๋”ฐ๋กœ ์กด์žฌํ•œ๋‹ค๋Š” ๋ฌธ์ œ๋„ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
     

     
     

    ์ด๋ฅผ ์œ„ํ•ด ์ง€๋„๋‚˜ ์žฅ์†Œ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์„ ํƒํ•œ ์ฃผ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•  ๊ฒฝ์šฐ currentCoord(์œ„๋„/๊ฒฝ๋„) ๊ฐ’์„ ๋ฐ”๊พธ๊ณ , currentCoord๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ ๋ณ€๊ฒฝ๋œ ์œ„๋„/๊ฒฝ๋„์— ๋งˆ์ปค๋ฅผ ์ฐ์–ด ์ฃผ๋„๋ก ๋กœ์ง์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์žฅ์†Œ ์„ ํƒ ๊ธฐ๋Šฅ์„ ์™„์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

     

    import { useEffect, useState } from 'react';
    
    import { TMap, TMapEvent, TMapLatLng, TMapMarker } from '@/types';
    
    const { Tmapv2 } = window;
    
    export const useMap = (mapRef: React.RefObject<HTMLDivElement>) => {
      const [mapInstance, setMapInstance] = useState<TMap | null>(null);
      const [currentMarker, setCurrentMarker] = useState<TMapMarker | null>(null);
      const [currentCoord, setCurrentCoord] = useState<TMapLatLng | null>(null);
    
      useEffect(() => {
        if (!currentCoord) {
          return;
        }
    
        const makeMarker = (position: TMapLatLng) => {
          if (!mapInstance) {
            return;
          }
    
          currentMarker?.setMap(null);
          
          const marker = new Tmapv2.Marker({
             position,
             map: mapInstance,
             icon: markerIcon,
             iconSize: new Tmapv2.Size(50, 50),
          })
    
          setCurrentMarker(marker);
        };
    
        makeMarker(currentCoord);
      }, [currentCoord, mapInstance]);
    
      useEffect(() => {
        if (!mapInstance) {
          return;
        }
    
        const changeCoord = (e: TMapEvent) => {
          const { latLng } = e;
          const position = new Tmapv2.LatLng(latLng.lat(), latLng.lng());
    
          setCurrentCoord(position);
        };
    
        mapInstance.addListener('click', changeCoord);
      }, [mapInstance, currentCoord]);
    };

     
     
     
     
     
     

    ํ›„๊ธฐ

    ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง€๋„ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋น„์Šค์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. TypeScript๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” API์˜ ํƒ€์ž…์„ ์ผ์ผ์ด ์ž‘์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์ฒ˜์Œ์—” ๊นŒ๋‹ค๋กœ์› ๊ณ , JavaScript์˜ ์˜ˆ์‹œ๋ฅผ React์— ์ ์šฉํ•˜๋ ค๋‹ค ๋ณด๋‹ˆ ์–ด๋ ค์šด ์ ๋„ ๋งŽ์•˜์ง€๋งŒ ๋ฌธ์ œ๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ๋ถ„์„ํ•˜๋ฉฐ ๋‹ค๋ฅธ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์„ ๋ชจ์ƒ‰ํ•˜๋Š” ๊ธธ์„ ํ†ตํ•ด ํ•œ ๊ฑธ์Œ ๋” ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ„๊ธฐ๊ฐ€ ๋˜์ง€ ์•Š์•˜๋‚˜ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. 
     
    TMap API๋ฅผ React์— ์ ์šฉํ•˜๋Š” ๊ธ€์ด ๋งŽ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ €์˜ ํฌ์ŠคํŒ…์œผ๋กœ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์—ˆ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์‹ถ์œผ์‹œ๋‹ค๋ฉด ๋ฆฌํŒฉํ† ๋ง ์ค‘์ธ ์ฝ”๋“œ์ง€๋งŒ ์ฐธ๊ณ ํ•ด ์ฃผ์‹œ๊ณ  โฌ‡๏ธโฌ‡๏ธโฌ‡๏ธ ๋” ๋งŽ์€ ๋„์›€์ด ํ•„์š”ํ•˜์‹œ๊ฑฐ๋‚˜ ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์˜๊ฒฌ์„ ๋‚จ๊ฒจ ์ฃผ์…”๋„ ์ข‹์Šต๋‹ˆ๋‹ค!
     
    https://github.com/boostcampwm2023/web17_morak/blob/develop/app/frontend/src/hooks/useMap.ts
     
     

    ๋Œ“๊ธ€

Designed by Tistory.