React - 확장성 있는 컴포넌트 설계, data fetching


✨ 컴포넌트 설계, data fetching

1const NoticeList = ({ category, searchValue, recentNoticeList }: Props) => {
2  const {
3    filterCondition,
4    sortCategory,
5    currentPageNumber,
6    listCategory,
7    noticeItemList,
8    updateItemList,
9    updateFilterCondition,
10    applyFilter,
11    updateSortCategory,
12    updatePageNumber,
13    setListCategory,
14    setNoticeItemList,
15  } = useNoticeListState(category, searchValue, recentNoticeList);
16
17  return (
18    <section className='flex flex-col items-center justify-center px-[12px] pb-[80px] pt-[40px] md:px-[32px] md:py-[60px] lg:px-0'>
19      <div className='flex flex-col gap-4 md:w-[650px] md:gap-8 lg:w-[971px]'>
20        <div className='flex w-full flex-col items-start gap-4 md:flex-row md:justify-between'>
21          <NoticeCategory category={category} searchValue={searchValue} />
22          {category !== 'recent' ? (
23            <NoticeListHeader
24              updateItemList={updateItemList}
25              filterCondition={filterCondition}
26              updateFilterCondition={updateFilterCondition}
27              applyFilter={applyFilter}
28              searchValue={searchValue}
29              sortCategory={sortCategory}
30              updateSortCategory={updateSortCategory}
31              updatePageNumber={updatePageNumber}
32              currentPageNumber={currentPageNumber}
33              setListCategory={setListCategory}
34              listCategory={listCategory}
35            />
36          ) : null}
37        </div>
38        <div className='grid grid-cols-2 grid-rows-3 gap-x-2 gap-y-4 md:gap-x-[14px] md:gap-y-[32px] lg:grid-cols-3 lg:grid-rows-2'>
39          {noticeItemList.items.length !== 0 ? (
40            noticeItemList.items.map(notice => {
41              const shopId = notice.item.shop.item.id;
42              const noticeId = notice.item.id;
43              return (
44                <Link key={noticeId} href={`/detail/${shopId}/${noticeId}`}>
45                  <Post key={noticeId} noticeItem={notice.item} />
46                </Link>
47              );
48            })
49          ) : (
50            <NoticeListLoading
51              category={category}
52              listCategory={listCategory}
53            />
54          )}
55        </div>
56      </div>
57      <Pagination
58        count={noticeItemList.count}
59        currentPageNumber={currentPageNumber}
60        updatePageNumber={updatePageNumber}
61        setNoticeItemList={setNoticeItemList}
62        sortCategory={sortCategory}
63        listCategory={listCategory}
64        searchValue={searchValue}
65        filterCondition={filterCondition}
66      />
67    </section>
68  );
69};
70
71export default NoticeList;

공고 목록 리스트를 보여주는 컴포넌트를 만들었다.

props로 넘겨줄 상태를 관리하는 부분과 커스텀 훅으로 뺀 건 이제 익숙하게 할 수 있겠다는 생각이 들었다.

하지만 부족했다고 생각하는 점이 있다.

  1. 공통 컴포넌트를 만들었는데, 특정 도메인이 묻은 점
    • 특정 도메인이 묻지 않은 범용성 있는 컴포넌트를 만드는 것이 어려운 것 같다. 기능 개발에 급급해 코드를 작성하다 보면, 항상 도메인이 묻어 나오는 것 같다.
  2. 데이터 상태 관리에 아직 익숙하지 않다는 점
    • next.js 에서 react-query는 필요하지 않을 수도 있다는 글을 봤다.
    • next.js를 사용하지 않는 react 프로젝트에서 react-query 를 사용해 상태를 관리, 또는
      next.js - server component 에서 확장된 fetch 함수 - 캐싱, revalidate 같은 기능을 이용해서 data fetching을 해야겠다.
  3. 부모 컴포넌트에서 데이터를 넘겨줄지, 자식 컴포넌트에서 fetch 해올지 고려하지 않고, 무분별하게 데이터를 fetching 했다는점.
    • 이 부분을 확실하게 하지 않고 컴포넌트를 만들다 보니, 이중으로 데이터를 불러온다거나, UI가 깜빡거리면서 재렌더링이 되어 성능과 UX 둘 다 만족스럽지 않았다.

next.js에서 권장하는 data fetching 방법 - 공식 문서

a. server component를 이용하여 서버측에서 데이터를 fetching 합니다.

b. data fetching은 병렬적으로 수행하는것이 좋습니다.

c. layout 및 page의 경우 데이터를 사용하는 곳에서 데이터를 가져오는것이 좋습니다.

d. Suspense, Loading UI를 이용해 점진적으로 렌더링을 수행하는것이 좋습니다.


위 사항을 고려해서 컴포넌트를 설계 해야겠다.