Skip to content

Commit d89c60a

Browse files
committed
[#101] refactor: 일부 리렌더링 리팩토링/예약 버튼 UI수정
1 parent 419bf6d commit d89c60a

File tree

9 files changed

+35
-22
lines changed

9 files changed

+35
-22
lines changed

src/app/(with-header)/activities/[id]/components/ActivityDetailForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import ReviewSection from './ReviewSection';
1414
import { AxiosError } from 'axios';
1515
import { notFound } from 'next/navigation';
1616

17-
import ActivityDetailSkeleton from './ActivityDetailSkeleton';
17+
import ActivityDetailSkeleton from './Skeletons/ActivityDetailSkeleton';
1818

1919
export default function ActivityDetailForm() {
20-
const [year, setYear] = useState(2025);
21-
const [month, setMonth] = useState(7);
20+
const [year, setYear] = useState(new Date().getFullYear());
21+
const [month, setMonth] = useState(new Date().getMonth() + 1);
2222

2323
const { id } = useParams();
2424

src/app/(with-header)/activities/[id]/components/ImageGrid.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
'use client';
22

33
import Image from 'next/image';
4-
import React, { useState } from 'react';
4+
import React, { useState, useMemo } from 'react';
55
import { ImageGridProps } from '@/types/activityDetailType';
66

7-
export default function ImageGrid({ mainImage, subImages }: ImageGridProps) {
7+
function ImageGrid({ mainImage, subImages }: ImageGridProps) {
88
const images = [mainImage, ...subImages];
9-
const [currentIndex, setCurrentIndex] = useState(0); //캐러셀 구현용 state
109

11-
// 첫번째 이미지면 마지막 이미지로 아니면 -1
10+
const [currentIndex, setCurrentIndex] = useState(0);
11+
1212
const prevSlide = () => {
1313
setCurrentIndex((prev) => (prev === 0 ? images.length - 1 : prev - 1));
1414
};
1515

16-
// 현재 마지막 이미지면 첫 이미지로 아니면 +1
1716
const nextSlide = () => {
1817
setCurrentIndex((prev) => (prev === images.length - 1 ? 0 : prev + 1));
1918
};
@@ -24,24 +23,24 @@ export default function ImageGrid({ mainImage, subImages }: ImageGridProps) {
2423
<div className='relative block aspect-square h-[300px] w-full overflow-hidden rounded-lg md:hidden'>
2524
<Image
2625
src={images[currentIndex]}
27-
alt={`${currentIndex + 1}`}
26+
alt={`슬라이드 이미지 ${currentIndex + 1}`}
2827
fill
2928
className='object-cover hover:animate-pulse'
3029
/>
31-
3230
<button
3331
onClick={prevSlide}
32+
aria-label='이전 이미지'
3433
className='absolute top-1/2 left-2 -translate-y-1/2 rounded-full bg-black/50 px-6 py-10 text-white'
3534
>
3635
3736
</button>
3837
<button
3938
onClick={nextSlide}
39+
aria-label='다음 이미지'
4040
className='absolute top-1/2 right-2 -translate-y-1/2 rounded-full bg-black/50 px-6 py-10 text-white'
4141
>
4242
4343
</button>
44-
4544
<div className='absolute bottom-2 left-1/2 flex -translate-x-1/2 gap-1'>
4645
{images.map((_, i) => (
4746
<div
@@ -81,3 +80,5 @@ export default function ImageGrid({ mainImage, subImages }: ImageGridProps) {
8180
</>
8281
);
8382
}
83+
84+
export default React.memo(ImageGrid);

src/app/(with-header)/activities/[id]/components/ReviewSection.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use client';
22

3+
import React from 'react';
34
import { useState, useCallback } from 'react';
45
import ReviewCard from './ReviewCard';
56
import Pagination from '@/components/Pagination';
@@ -24,7 +25,7 @@ interface ReviewProps {
2425
content: string;
2526
}
2627

27-
export default function ReviewSection({
28+
function ReviewSection({
2829
activityId,
2930
reviewCount,
3031
rating,
@@ -103,3 +104,5 @@ export default function ReviewSection({
103104
</div>
104105
);
105106
}
107+
108+
export default React.memo(ReviewSection);

src/app/(with-header)/activities/[id]/components/ActivityDetailSkeleton.tsx renamed to src/app/(with-header)/activities/[id]/components/Skeletons/ActivityDetailSkeleton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22

3-
import SkeletonBookingInterface from './Skeletons/BookingInterfaceSkeleton';
3+
import SkeletonBookingInterface from './BookingInterfaceSkeleton';
44
import useUserStore from '@/stores/authStore';
55

66
export default function ActivityDetailSkeleton({ userId }: { userId: number }) {

src/app/(with-header)/activities/[id]/components/Title.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ interface TitleProps {
2121
isOwner: boolean;
2222
}
2323

24-
export default function Title({
24+
function Title({
2525
title,
2626
category,
2727
rating,
@@ -90,3 +90,5 @@ export default function Title({
9090
</>
9191
);
9292
}
93+
94+
export default React.memo(Title);

src/app/globals.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@import 'tailwindcss';
2-
@import "tw-animate-css";
2+
@import 'tw-animate-css';
33

44
@custom-variant dark (&:is(.dark *));
55

src/components/DatePicker/DatePicker.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use client';
22

33
import { useEffect, useState } from 'react';
4+
import { shallow } from 'zustand/shallow';
45
import dayjs from 'dayjs';
56
import weekday from 'dayjs/plugin/weekday';
67
import isoWeek from 'dayjs/plugin/isoWeek';
@@ -11,6 +12,7 @@ import CalendarHeader from './CalendarHeader';
1112
import CalendarBody from './CalendarBody';
1213
import useBookingStore from '@/stores/Booking/useBookingStore';
1314
import { SchedulesProps } from '@/types/activityDetailType';
15+
import { BookingState } from '@/types/bookingStoreTypes';
1416

1517
dayjs.extend(weekday);
1618
dayjs.extend(isoWeek);
@@ -24,9 +26,11 @@ export default function DatePicker({
2426
schedules: SchedulesProps;
2527
onMonthChange?: (year: number, month: number) => void;
2628
}) {
27-
const { selectedDate, setSelectedDate, setAvailableDates, availableDates } =
28-
useBookingStore();
29-
29+
const selectedDate = useBookingStore((state) => state.selectedDate);
30+
const setSelectedDate = useBookingStore((state) => state.setSelectedDate);
31+
const setAvailableDates = useBookingStore((state) => state.setAvailableDates);
32+
const availableDates = useBookingStore((state) => state.availableDates);
33+
3034
const today = dayjs();
3135

3236
const [viewDate, setViewDate] = useState(() =>

src/components/FloatingBox/BookingInterface.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,11 @@ export default function BookingInterface({
152152
)}
153153
</div>
154154
<BookingModal schedules={schedules} price={price} />
155-
<BookingButton disabled={!isBookable} onClick={handleBooking}>
156-
{buttonText}
157-
</BookingButton>
155+
<div className='flex justify-center'>
156+
<BookingButton disabled={!isBookable} onClick={handleBooking}>
157+
{buttonText}
158+
</BookingButton>
159+
</div>
158160
</div>
159161
</div>
160162
</div>

src/components/LocationMap.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { useEffect, useState, useRef } from 'react';
44
import { Map, MapMarker, CustomOverlayMap } from 'react-kakao-maps-sdk';
55
import Location from '@assets/svg/location';
6+
import React from 'react';
67

78
interface LocationMapProps {
89
address: string;
@@ -108,4 +109,4 @@ const LocationMap = ({ address }: LocationMapProps) => {
108109
);
109110
};
110111

111-
export default LocationMap;
112+
export default React.memo(LocationMap);

0 commit comments

Comments
 (0)