From b98e2bfa07b45399e1fbcdf379b5ef19c713e7cc Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:10:57 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20scrip?= =?UTF-8?q?t=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 간헐적으로 웹사이트 자체 로딩에 시간이 매우 많이 소요되는 문제가 있었음 --- public/index.html | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/public/index.html b/public/index.html index 3f4f1c77..d7658dc8 100644 --- a/public/index.html +++ b/public/index.html @@ -9,10 +9,6 @@ name="description" content="Web site created using create-react-app" /> - @@ -25,4 +21,4 @@
- + \ No newline at end of file From c592eaa4cde58d902d2dbe8b6caed0deff8c350d Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:12:06 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=A7=80=EB=8F=84=20=EC=9B=B9=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EC=A3=BC=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이에 따라 kakao.maps.load 메소드 사용 --- src/pages/map/useMap.ts | 56 ++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/pages/map/useMap.ts b/src/pages/map/useMap.ts index 09315632..af2f76b2 100644 --- a/src/pages/map/useMap.ts +++ b/src/pages/map/useMap.ts @@ -36,33 +36,43 @@ function useMap( ); useEffect(() => { - (() => { - if (!containerRef.current) return; - setMap( - new window.kakao.maps.Map(containerRef.current, { - center: new window.kakao.maps.LatLng(35.1759293, 126.9149701), - level: 3, - }), - ); - function placesSearchCB(data: any[], status: any) { - if (status === kakao.maps.services.Status.OK) { - const bounds = new kakao.maps.LatLngBounds(); + const mapScript = document.createElement('script'); + mapScript.async = true; + mapScript.src = `https://dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.REACT_APP_KAKAO_KEY}&libraries=services&autoload=false`; + document.head.appendChild(mapScript); - for (let i = 0; i < data.length; i += 1) { - bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x)); + const onLoadKakaoMap = () => { + if (!containerRef.current || !kakao) return; + window.kakao.maps.load(() => { + setMap( + new window.kakao.maps.Map(containerRef.current, { + center: new window.kakao.maps.LatLng(35.1759293, 126.9149701), + level: 3, + }), + ); + + function placesSearchCB(data: any[], status: any) { + if (status === kakao.maps.services.Status.OK) { + const bounds = new kakao.maps.LatLngBounds(); + + for (let i = 0; i < data.length; i += 1) { + bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x)); + } + boundRef.current = bounds; } - boundRef.current = bounds; + setSearchedPlace(data); } - setSearchedPlace(data); - } - const ps = new kakao.maps.services.Places(); // 키워드로 장소를 검색합니다 - ps.keywordSearch('보호소', placesSearchCB, { - location: new kakao.maps.LatLng(35.1759293, 126.9149701), - radius: 20000, - sort: kakao.maps.services.SortBy.DISTANCE, + const ps = new kakao.maps.services.Places(); // 키워드로 장소를 검색합니다 + ps.keywordSearch('보호소', placesSearchCB, { + location: new kakao.maps.LatLng(35.1759293, 126.9149701), + radius: 20000, + sort: kakao.maps.services.SortBy.DISTANCE, + }); }); - })(); - }, [containerRef]); + }; + mapScript.addEventListener('load', onLoadKakaoMap); + onLoadKakaoMap(); + }, [containerRef, kakao]); return { map, displayMarkerByInfo, searchedPlace, mutate, mutateData }; } From efa89d37ab4afea6588d2ebd89611866b4e0f611 Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:13:34 +0900 Subject: [PATCH 3/9] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/map/MapList.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/map/MapList.tsx b/src/pages/map/MapList.tsx index 5f4188b3..d8aed776 100644 --- a/src/pages/map/MapList.tsx +++ b/src/pages/map/MapList.tsx @@ -24,6 +24,7 @@ const MapList = ({ map, }: { searchedPlace: SearchedPlace[]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any map: any; }) => { const { kakao } = window; @@ -44,8 +45,6 @@ const MapList = ({ return 0; }); - const infowindow = new kakao.maps.InfoWindow({ zIndex: 1 }); - return (
{searchedPlace.map((place) => ( From 345c1aebacbb316423525b2d3a45efb72f84ee59 Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:35:16 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20=EC=A7=80=EB=8F=84=20=EC=8A=A4?= =?UTF-8?q?=EC=BC=88=EB=A0=88=ED=86=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/map/MapSkeleton.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/pages/map/MapSkeleton.tsx diff --git a/src/pages/map/MapSkeleton.tsx b/src/pages/map/MapSkeleton.tsx new file mode 100644 index 00000000..8b151d3b --- /dev/null +++ b/src/pages/map/MapSkeleton.tsx @@ -0,0 +1,17 @@ +const MapSkeleton = ({ listSize }: { listSize: number }) => { + return ( + <> +
+
+ {Array.from({ length: listSize }).map((_, index) => ( +
+ ))} +
+ + ); +}; + +export default MapSkeleton; From fbcf76e2596dbdcdf4d08a48bdb72176c9d78678 Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:35:59 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20=EC=A7=80=EB=8F=84=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=20=EC=83=81=ED=83=9C=20=EA=B4=80=EB=A6=AC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=83=81=ED=83=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/map/Map.tsx | 13 ++++++++----- src/pages/map/MapList.tsx | 6 ++++++ src/pages/map/useMap.ts | 2 ++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/pages/map/Map.tsx b/src/pages/map/Map.tsx index 29af18c0..52e919e1 100644 --- a/src/pages/map/Map.tsx +++ b/src/pages/map/Map.tsx @@ -7,8 +7,9 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-use-before-define */ /* eslint-disable no-new */ -import React, { useEffect, useRef } from 'react'; -import MapList, { SearchedPlace } from './MapList'; +import { useState, useEffect, useRef } from 'react'; +import MapList from './MapList'; +import MapSkeleton from './MapSkeleton'; import useMap from './useMap'; declare global { @@ -18,8 +19,9 @@ declare global { } const Map: React.FC = () => { const mapRef = useRef(null); + const [loading, setLoading] = useState(true); const { map, displayMarkerByInfo, searchedPlace, mutate, mutateData } = - useMap(mapRef); + useMap(mapRef, setLoading); useEffect(() => { mutate(searchedPlace); }, [searchedPlace]); @@ -40,8 +42,9 @@ const Map: React.FC = () => { return (
-
- +
+ {loading && } +
); }; diff --git a/src/pages/map/MapList.tsx b/src/pages/map/MapList.tsx index d8aed776..a7f20681 100644 --- a/src/pages/map/MapList.tsx +++ b/src/pages/map/MapList.tsx @@ -22,10 +22,12 @@ export interface SearchedPlace { const MapList = ({ searchedPlace, map, + loading, }: { searchedPlace: SearchedPlace[]; // eslint-disable-next-line @typescript-eslint/no-explicit-any map: any; + loading: boolean; }) => { const { kakao } = window; const navigate = useNavigate(); @@ -45,6 +47,10 @@ const MapList = ({ return 0; }); + if (loading) { + return <>; + } + return (
{searchedPlace.map((place) => ( diff --git a/src/pages/map/useMap.ts b/src/pages/map/useMap.ts index af2f76b2..90b8e5a3 100644 --- a/src/pages/map/useMap.ts +++ b/src/pages/map/useMap.ts @@ -5,6 +5,7 @@ import displayMarker from './displayMarker'; function useMap( containerRef: RefObject, + setLoading: React.Dispatch>, ) { const { kakao } = window; const [map, setMap] = useState(); @@ -69,6 +70,7 @@ function useMap( sort: kakao.maps.services.SortBy.DISTANCE, }); }); + setLoading(false); }; mapScript.addEventListener('load', onLoadKakaoMap); onLoadKakaoMap(); From d539400a77c0cbb9f2437ea048404fde5affb7e0 Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:36:52 +0900 Subject: [PATCH 6/9] =?UTF-8?q?style:=20React.FC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 코드 스타일 통일 --- src/pages/map/Map.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/map/Map.tsx b/src/pages/map/Map.tsx index 52e919e1..3d79edcb 100644 --- a/src/pages/map/Map.tsx +++ b/src/pages/map/Map.tsx @@ -17,7 +17,8 @@ declare global { kakao: any; } } -const Map: React.FC = () => { + +const Map = () => { const mapRef = useRef(null); const [loading, setLoading] = useState(true); const { map, displayMarkerByInfo, searchedPlace, mutate, mutateData } = From 88258f0ae666f92498caeaddaf3f2bd14636c31d Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:44:19 +0900 Subject: [PATCH 7/9] =?UTF-8?q?feat:=20AddressInfo=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/map/displayMarker.ts | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/pages/map/displayMarker.ts b/src/pages/map/displayMarker.ts index 89836bcd..841f5eb7 100644 --- a/src/pages/map/displayMarker.ts +++ b/src/pages/map/displayMarker.ts @@ -1,7 +1,23 @@ -const displayMarker = async (map: any, addressInfo: any) => { +export interface AddressInfo { + address_name: string; + category_group_code: string; + category_group_name: string; + category_name: string; + distance: string; + id: string; + phone: string; + place_name: string; + place_url: string; + road_address_name: string; + x: string; + y: string; + isRegistered: boolean; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const displayMarker = async (map: any, addressInfo: AddressInfo) => { const { kakao } = window; - // eslint-disable-next-line @typescript-eslint/naming-convention - const { isRegistered, x: lng, y: lat, place_name } = addressInfo; + const { isRegistered, x: lng, y: lat, place_name: placeName } = addressInfo; const DEFAULT_SHELTER_SRC = '/assets/images/racoon.png'; const ANYMORY_SHELTER_SRC = '/assets/images/dog.png'; @@ -25,7 +41,7 @@ const displayMarker = async (map: any, addressInfo: any) => { const infowindow = new kakao.maps.InfoWindow({ zIndex: 1 }); kakao.maps.event.addListener(marker, 'click', () => { infowindow.setContent( - `
${place_name}
`, + `
${placeName}
`, ); infowindow.open(map, marker); setTimeout(() => { From 76ba02abd9394f74cd264a1cf7e6decf5c930130 Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:45:25 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20AddressInfo=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/map/useMap.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/map/useMap.ts b/src/pages/map/useMap.ts index 90b8e5a3..3906a795 100644 --- a/src/pages/map/useMap.ts +++ b/src/pages/map/useMap.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { useEffect, useState, RefObject, useRef } from 'react'; import { useMutation } from '@tanstack/react-query'; -import displayMarker from './displayMarker'; +import displayMarker, { AddressInfo } from './displayMarker'; function useMap( containerRef: RefObject, @@ -12,7 +12,7 @@ function useMap( const [searchedPlace, setSearchedPlace] = useState([]); const boundRef = useRef(); - const displayMarkerByInfo = async (addressInfo: any) => { + const displayMarkerByInfo = async (addressInfo: AddressInfo) => { if (!map) return; map.setBounds(boundRef.current); await displayMarker(map, addressInfo); From 807f97a62b81cc0c85043c84b4a629befb382541 Mon Sep 17 00:00:00 2001 From: hjiwon Date: Wed, 8 Nov 2023 18:49:24 +0900 Subject: [PATCH 9/9] =?UTF-8?q?refactor:=20=EB=AF=B8=EB=A6=AC=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8=ED=96=88=EB=8D=98=20=EC=9D=B8=ED=84=B0=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/map/displayMarker.ts | 18 ++---------------- src/pages/map/useMap.ts | 5 +++-- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/pages/map/displayMarker.ts b/src/pages/map/displayMarker.ts index 841f5eb7..11002c5f 100644 --- a/src/pages/map/displayMarker.ts +++ b/src/pages/map/displayMarker.ts @@ -1,21 +1,7 @@ -export interface AddressInfo { - address_name: string; - category_group_code: string; - category_group_name: string; - category_name: string; - distance: string; - id: string; - phone: string; - place_name: string; - place_url: string; - road_address_name: string; - x: string; - y: string; - isRegistered: boolean; -} +import { SearchedPlace } from './MapList'; // eslint-disable-next-line @typescript-eslint/no-explicit-any -const displayMarker = async (map: any, addressInfo: AddressInfo) => { +const displayMarker = async (map: any, addressInfo: SearchedPlace) => { const { kakao } = window; const { isRegistered, x: lng, y: lat, place_name: placeName } = addressInfo; diff --git a/src/pages/map/useMap.ts b/src/pages/map/useMap.ts index 3906a795..232827ec 100644 --- a/src/pages/map/useMap.ts +++ b/src/pages/map/useMap.ts @@ -1,7 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { useEffect, useState, RefObject, useRef } from 'react'; import { useMutation } from '@tanstack/react-query'; -import displayMarker, { AddressInfo } from './displayMarker'; +import displayMarker from './displayMarker'; +import { SearchedPlace } from './MapList'; function useMap( containerRef: RefObject, @@ -12,7 +13,7 @@ function useMap( const [searchedPlace, setSearchedPlace] = useState([]); const boundRef = useRef(); - const displayMarkerByInfo = async (addressInfo: AddressInfo) => { + const displayMarkerByInfo = async (addressInfo: SearchedPlace) => { if (!map) return; map.setBounds(boundRef.current); await displayMarker(map, addressInfo);