1. 초기접근: useState 를 이용한 구현
검색영역과 뷰 영역을 분리하고 있는 와중에 처음에는 단순히 useState를 사용하여 구현을 시도했습니다:
const [searchParams, setSearchParams] = useState({
searchText: "",
lastId: DEFAULT_LAST_ID_DESC
});
const [customerList, setCustomerList] = useState([]);
하지만 이 방식에는 몇 가지 문제가 있었습니다:
1. 상태 동기화 문제
- setState는 비동기적으로 동작하기 때문에, 더보기 클릭 시 이전 상태값을 참조하는 문제 발생
- API 호출 시점과 상태 업데이트 시점의 불일치
2. 데이터 관리의 복잡성
- 기존 목록에 새로운 데이터를 추가하는 로직이 복잡해짐
- 중복 데이터 처리나 에러 상황 대응이 어려움
2. Jotai를 사용한 시도
다음으로 전역 상태 관리를 위해 Jotai를 시도했습니다:
const searchParamsAtom = atom({
searchText: "",
lastId: DEFAULT_LAST_ID_DESC
});
하지만 이 역시 useState와 비슷한 문제에 직면했습니다:
1. 상태 업데이트 타이밍
- useState와 비슷한 동작 방식으로 인해 상태 업데이트 타이밍 이슈 지속
- 더보기 시 이전 lastId를 참조하는 문제 해결되지 않음
2. 데이터 페칭 로직과의 통합
- 상태 관리와 데이터 페칭 로직이 여전히 분리되어 있어 복잡성 존재
3. 최종 해결책: React Query의 useInfiniteQuery
결국 React Query의 useInfiniteQuery를 사용하여 문제를 해결했습니다:
const {
data,
fetchNextPage,
hasNextPage,
refetch,
isFetchingNextPage
} = useInfiniteQuery({
queryKey: [QUERY_KEY, searchParams],
queryFn: ({ pageParam = DEFAULT_LAST_ID_DESC }) =>
fetchGet("/api/v1/admin/customer/manage", {
searchText: searchParams.searchText,
lastId: pageParam
}),
getNextPageParam: (lastPage) => {
if (lastPage.data.length !== searchParams.size) {
return undefined;
}
return lastPage.lastId;
}
});
1. 자동화된 상태 관리
- 페이지네이션 상태를 자동으로 관리
- 캐시 처리가 내장되어 있어 성능 최적화 용이
2. 직관적인 API
- fetchNextPage, hasNextPage 등 필요한 기능이 이미 구현되어 있음
- 로딩 상태 관리가 간편함
3. 데이터 무결성
- 캐시와 실제 데이터의 동기화가 자동으로 처리됨
- 중복 요청 방지 기능 내장
주요기능 사용:
더보기: 다음 데이터를 불러오는데 추가 코딩 없이 함수 한번으로 바로 호출되는 점이 좋았습니다
const handleAddSearch = () => {
if (!hasNextPage) {
toast.warn("더 이상 데이터가 없습니다.");
return;
}
fetchNextPage();
};
검색초기화: refetch 를 쓰면 첫페이지로 돌아가는게 아니라 지금까지 불러왔던것을 순서대로 모두 불러오고 있었습니다. 제가원한건 첫페이지로 이동하는 것이기 떄문이 catch 를 제거함으로써 갱신되도록 개발했습니다.
const handleSearch = async () => {
await queryClient.resetQueries([QUERY_KEY, searchParams]);
refetch();
};
4. 배운 점
상태 관리 도구 선택의 중요성
- 단순 상태 관리 vs 데이터 페칭 관리
- 각 도구의 특성과 적절한 사용 상황
React Query의 강점
- 데이터 페칭에 특화된 기능
- 캐시 관리의 편리함
- 무한 스크롤/더보기 구현의 용이성
성능 최적화
- 불필요한 리렌더링 방지
- 효율적인 데이터 캐싱
- 사용자 경험 개선
결론
복잡한 데이터 페칭과 상태 관리가 필요한 경우, React Query와 같은 전문화된 도구를 사용하는 것이 더 효율적입니다. 특히 무한 스크롤이나 더보기 기능 구현 시 useInfiniteQuery가 개발편리한 기능을 많이 제공합니다.
댓글