Skip to content

Commit c4c41ed

Browse files
authored
Refactor: 검색/필터링 기능 최적화 (#86)
* refactor: useEffect 제거 * refactor: 불필요 useEffect 삭제 및 컴포넌트 분리 * feat: useAsyncEffect deps 옵셔널로 변경 * refactor: 불필요 useEffect 제거 * refactor: useEffect 로 body overflow 관리하기 * refactor: 필요 없는 옵셔널체이닝 제거 * chore: hook 관련 eslint 추가 * refactor: 검색 필터링 방식 변경 * chore: typescript 버전 업 * refactor: 리렌더링 최적화 * refactor: 중복된 setState 함수 호출 리팩토링 * feat: 이미지 배경색상 핑크 없애기 * feat: place card image lazy loading 추가 * refactor: 컴포넌트 분리 * fix: filterIndexInfo 유지되는 문제 해결
1 parent 32eb684 commit c4c41ed

File tree

23 files changed

+379
-297
lines changed

23 files changed

+379
-297
lines changed

.eslintrc.cjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module.exports = {
1313
'plugin:@typescript-eslint/recommended',
1414
'plugin:react/recommended',
1515
'prettier',
16+
'plugin:react-hooks/recommended',
1617
],
1718
overrides: [
1819
{

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"stylelint-config-standard": "^36.0.1",
5151
"stylelint-order": "^6.0.4",
5252
"terser": "^5.31.1",
53-
"typescript": "^5.2.2",
53+
"typescript": "^5.5.4",
5454
"vite": "^5.3.1",
5555
"vite-plugin-svgr": "^4.2.0",
5656
"vite-tsconfig-paths": "^4.3.2"

pnpm-lock.yaml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/MenuBar.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { css } from '@emotion/react';
2-
import { useState } from 'react';
2+
import { memo, useState } from 'react';
33
import { useLocation, useNavigate } from 'react-router-dom';
44

55
import {
@@ -20,7 +20,7 @@ const PATH_MATCH = [
2020
{ url: '/mypage', name: '마이', icon: <UserMonoIcon /> },
2121
];
2222

23-
const MenuBar = () => {
23+
const MenuBar = memo(() => {
2424
const { pathname } = useLocation();
2525
const firstPathname = `/${pathname.split('/')[1]}`;
2626
const navigate = useNavigate();
@@ -67,14 +67,17 @@ const MenuBar = () => {
6767
{activateModal && <LoginModal onClick={closeModal} />}
6868
</>
6969
);
70-
};
70+
});
71+
72+
MenuBar.displayName = 'MenuBar';
7173

7274
export default MenuBar;
7375

7476
const navCss = css`
7577
display: flex;
7678
position: fixed;
7779
bottom: 1.6rem;
80+
z-index: 999;
7881
7982
width: 100vw;
8083
`;

src/components/PageLoading.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
import { css } from '@emotion/react';
2-
import { useEffect } from 'react';
32

43
import { WhiteSpinnerGIF } from '@/assets/image';
54
import { COLORS, FONTS } from '@/styles/constants';
65

76
const PageLoading = () => {
8-
useEffect(() => {
9-
// 스크롤 방지
10-
document.body.style.overflow = 'hidden';
11-
12-
return () => {
13-
document.body.style.overflow = 'auto';
14-
};
15-
}, []);
167
return (
178
<div css={dataContainer}>
189
<img css={img} src={WhiteSpinnerGIF} alt="spinner" />
@@ -32,10 +23,10 @@ const dataContainer = css`
3223
top: 0;
3324
z-index: 999;
3425
35-
width: 100dvw;
3626
width: 100%;
37-
height: 100dvh;
27+
width: 100dvw;
3828
height: 100%;
29+
height: 100dvh;
3930
4031
background-color: rgb(82 82 82 / 72%);
4132
`;

src/components/PlaceCard.tsx

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import { COLORS, FONTS } from '@/styles/constants';
1111

1212
interface PlaceCardProps {
13+
idx: number;
1314
placeName: string;
1415
address: string;
1516
imgSrc: string;
@@ -30,6 +31,7 @@ interface PlaceCardProps {
3031

3132
const PlaceCard = (props: PlaceCardProps) => {
3233
const {
34+
idx,
3335
placeName,
3436
address,
3537
imgSrc,
@@ -47,7 +49,13 @@ const PlaceCard = (props: PlaceCardProps) => {
4749
};
4850

4951
return (
50-
<Link to={`/${contentid}`} css={cardContainerCss(imgSrc, placeName)}>
52+
<Link to={`/${contentid}`} css={cardContainerCss(placeName)}>
53+
<img
54+
src={imgSrc}
55+
alt=""
56+
loading={idx > 10 ? 'lazy' : 'eager'}
57+
css={imgCss}
58+
/>
5159
<div css={backgroundCss}>
5260
<button
5361
type="button"
@@ -73,7 +81,7 @@ const PlaceCard = (props: PlaceCardProps) => {
7381

7482
export default PlaceCard;
7583

76-
const cardContainerCss = (imgSrc: string, placeName: string) => css`
84+
const cardContainerCss = (placeName: string) => css`
7785
display: flex;
7886
flex-direction: column;
7987
position: relative;
@@ -83,15 +91,26 @@ const cardContainerCss = (imgSrc: string, placeName: string) => css`
8391
border-radius: 1.2rem;
8492
8593
background-color: ${placeName ? COLORS.gray4 : COLORS.gray2};
86-
background-position: center center;
87-
background-size: cover;
88-
background-image: url(${imgSrc});
94+
`;
95+
96+
const imgCss = css`
97+
position: absolute;
98+
top: 0;
99+
left: 0;
100+
z-index: 1;
101+
102+
width: 100%;
103+
height: 16.8rem;
104+
border-radius: 1.2rem;
105+
106+
object-fit: cover;
89107
`;
90108

91109
const backgroundCss = css`
92110
position: absolute;
93111
top: 0;
94112
left: 0;
113+
z-index: 2;
95114
96115
width: 100%;
97116
height: 16.8rem;

src/constants/facilities.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ import {
8888
WheelChairInAcitveIcon,
8989
WheelChairSelectedIcon,
9090
} from '@/assets/icon';
91-
import { BarrierFreeItem } from '@/types/search';
91+
import { FilterFacilities } from '@/views/Search/types/category';
9292

9393
export interface Facility {
9494
name: string;
@@ -264,7 +264,7 @@ export const INFANT_FACILITIES: Facility[] = [
264264
},
265265
];
266266

267-
export const MAP_FACILITIES_API_KEY: Record<string, keyof BarrierFreeItem> = {
267+
export const MAP_FACILITIES_API_KEY: Record<string, FilterFacilities> = {
268268
휠체어: 'wheelchair',
269269
출입통로: 'exit',
270270
엘리베이터: 'elevator',

src/hooks/use-async-effect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect } from 'react';
22

33
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4-
export const useAsyncEffect = (effect: () => Promise<void>, deps: any[]) => {
4+
export const useAsyncEffect = (effect: () => Promise<void>, deps?: any[]) => {
55
useEffect(() => {
66
effect();
77
}, deps);

src/hooks/use-infinite-scroll.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const useInfiniteScroll = ({
3838
target.current && observer.observe(target.current);
3939

4040
return () => {
41+
//주시 종료
4142
target.current && observer.unobserve(target.current);
4243
};
4344
}, deps);

src/views/Detail/components/Review.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { css } from '@emotion/react';
2-
import { useEffect, useState } from 'react';
2+
import { useState } from 'react';
33
import { useLocation, useParams } from 'react-router-dom';
44

55
import getReviews from '@/apis/supabase/getReviews';
@@ -67,14 +67,12 @@ const Review = () => {
6767
setFilterState(value);
6868
};
6969

70-
const selectedFilterList = getFilterList(filterState);
70+
if (sessionStorage.getItem(STORAGE_KEY.successToast)) {
71+
setToast(true);
72+
sessionStorage.removeItem(STORAGE_KEY.successToast);
73+
}
7174

72-
useEffect(() => {
73-
if (sessionStorage.getItem(STORAGE_KEY.successToast)) {
74-
setToast(true);
75-
sessionStorage.removeItem(STORAGE_KEY.successToast);
76-
}
77-
}, []);
75+
const selectedFilterList = getFilterList(filterState);
7876

7977
useAsyncEffect(async () => {
8078
setLoading(true);

0 commit comments

Comments
 (0)