스터디 멤버들의 회고록 데이터여서 양이 그렇게 많지 않아 데이터 전체를 불러와 클라이언트에서 더보기 처리를 하였다.
만약 서버에서 많은 데이터를 불러오는 경우라면 API 호출 로직을 수정해야 할 것이다.
구현 기능
- 초기에 4개의 메모만 표시되고, 더보기 버튼을 클릭할 때마다 4개씩 추가로 메모가 표시됨
- 더 이상 표시할 메모가 없으면 더보기 버튼이 사라짐
구현 과정
1. useState 훅을 사용해 초기값이 4인 showItems 상태를 관리
const [showItems, setShowItem] = useState(4);
2. handleLoadMore 함수를 추가해 더보기 버튼 클릭 시 showItems + 4씩 증가
const handleLoadMore = () => {
setShowItem((prev) => prev + 4);
};
3. displayedMemos : data 배열에서 showItems 개수만큼 잘라낸 배열
const displayedMemos = data.slice(0, showItems);
4. hasMoreMemos 변수를 사용해 더 표시할 메모가 있는지 확인
const hasMoreMemos = showItems < data.length;
5. hasMoreMemos가 true일 때만 더보기 버튼 렌더링
{hasMoreMemos && (
<button
onClick={handleLoadMore}
className="caption mt-5 flex items-center justify-center text-secondary-300"
>
<span>더보기</span>
<Image
src={"/icons/ChevronDownGray.svg"}
alt="down"
width={20}
height={20}
/>
</button>
)}
전체 코드
"use client";
import Image from "next/image";
import { useStudyMemo } from "../[id]/hooks/usePersonalMemo";
import PersonalMemoItem from "./PersonalMemoItem";
import { useState } from "react";
import Loading from "@/components/common/Loading";
const PersonalMemos = ({ studyId }: { studyId: string }) => {
const { data, isLoading, isError } = useStudyMemo(studyId);
const [showItems, setShowItem] = useState(4);
if (isLoading || !data) {
return <Loading />;
}
if (isError) {
return <div>회고록 목록을 불러오는데 실패했습니다.</div>;
}
// 더보기
const handleLoadMore = () => {
setShowItem((prev) => prev + 4);
};
// data 배열에서 showItems 개수만큼 잘라낸 배열
const displayedMemos = data.slice(0, showItems);
// 표시할 메모가 있는지 확인
const hasMoreMemos = showItems < data.length;
return (
<div className="mb-[55px] flex w-full flex-col">
<div className="mb-3 flex items-center p-1 pl-1">
<Image src={"/icons/StudyMemo.svg"} alt="memo" width={16} height={16} />
<h2 className="caption ml-1 text-white">스터디 회고록</h2>
</div>
{displayedMemos.map((item) => (
<PersonalMemoItem key={item.memo_id} memoData={item} />
))}
{hasMoreMemos && (
<button
onClick={handleLoadMore}
className="caption mt-5 flex items-center justify-center text-secondary-300"
>
<span>더보기</span>
<Image
src={"/icons/ChevronDownGray.svg"}
alt="down"
width={20}
height={20}
/>
</button>
)}
</div>
);
};
export default PersonalMemos;
🧐 느낀점
현재는 데이터 양이 적은 스터디 회고록이라 클라이언트 사이드에서 처리를 했지만, 대량의 데이터를 불러올 경우 적합하지 않을 것 같다.
그런 경우에는 페이지네이션이나 무한 스크롤을 서버 사이드에서 구현하는 것이 클라이언트의 메모리 관리나 초기 로딩 시간 측면에서 더 효율적일거라 생각된다. 작은 기능이지만, 프로젝트의 규모와 특성에 따라 구현 방식을 달리 해야할 듯하다.
'TIL' 카테고리의 다른 글
favicon & og 설정하기 (0) | 2024.11.14 |
---|---|
아키텍쳐, 다이어그램, 기능명세서 만들기 (0) | 2024.11.13 |
css 우선순위 문제 (0) | 2024.11.11 |
자체 UT 후 계획 및 버그수정 (1) | 2024.11.08 |
shadcn/ui 캘린더 css 적용하기 (0) | 2024.11.06 |