Next.js + TanStack Query로 페이지 이동 시 데이터 전달하기

박민형·2023년 7월 8일
0
post-thumbnail

SP3가 끝나갈 때 쯤 프론트, 백엔드 전체 회의를 하던 중에 독서 모임 수정페이지 제작이 필요할 것 같다는 의견이 나왔다. 해당 페이지를 누가 제작할 것 인지 회의를 했고 다른 팀원 분들의 잔여 작업이 있는 것 같아서 내가 맡기로 했다.

📌 독서 모임 수정 페이지에 독서 모임 상세 페이지 데이터가 필요한 이유

  • 처음에는 독서 모임 상세 페이지에서 수정 버튼을 누르면 아무 데이터도 입력되지 않은 폼을 render하고 있는 독서 모임 수정 페이지로 이동했다.
  • 페이지만 보고는 아무런 문제를 느끼지 못했다. 하지만 사용자 입장에서 UX를 고려해봤을 때 독서 모임 상세 페이지의 데이터가 render 되도록 하는 것이 어떨까라는 생각을 했다.
  • 몇개의 단어만 수정한다거나 하나의 정보만 수정하는 상황인데 모든 데이터를 다시 입력 및 선택(사용자가 이전 데이터를 기억하지 못할 수도 있음)하는 것은 UX에 좋지 않을 것이라 생각해 작업을 진행하기로 했다.

📌 페이지 이동 시 데이터 전달 받는 방법

  • 페이지 이동 시 이전 페이지에서 데이터를 전달하고 현재 페이지가 데이터를 전달 받는 경우도 있고, 이전 페이지에서 데이터를 전달하지 않아도 현재 페이지에서 데이터를 전달 받을 수 있는 경우도 있었다!

🔎 데이터 전달 및 전달 받기

  • useRouter push 함수의 객체 필드 query 사용
    • 독서 모임 상세 페이지에서 query의 value로 객체를 전달
    • 독서 모임 수정 페이지에서 query를 구조 분해 할당 후 데이터 사용
// 독서 모임 상세 페이지
router.push({
  pathname: '/recruit/update',
  query: { title, description, meeting_type... }
});
// 독서 모임 수정 페이지
const {
  query: { title, description, meeting_type... },
  push,
} = useRouter();

🔎 데이터 전달 없이 전달 받기 1

  • 독서 모임 상세 페이지에서 캐싱된 데이터를 사용하는 방법(내가 사용한 방법)
    • 현재 TanStack Query의 useQuery를 통해 독서 모임 상세 페이지에서 render할 데이터를 fetch하고 있다!
    // 상세 페이지
    const {
      data: groupData,
      isError: isGroupError,
      isLoading: isGroupLoading,
    } = useQuery(
      ['recruitDetail', groupId],
      () => fetchReadingGroupInfo(groupId as string),
      {
        staleTime: 1000 * 60,
      },
    );
    • 독서 모임 수정 페이지에서도 해당 코드를 사용해 현재 ['recruitDetail', groupId]가 key인 query에 캐싱된 데이터를 사용
    • staleTime을 Infinity로 설정한 이유는 수정 페이지는 무조건 상세 페이지로 부터 접근할 수 있다(종속 관계) 생각했고 그러므로 상세페이지가 수정되지 않는 한 계속 fresh한 데이터로 간주하기로 했다.(아직 사용자 입장에서 여러 상황 및 cacheTime 설정을 고려하지 않았기 때문에 에러가 발생할 수 있는데 추후에 리팩토링 할 예정이다!)
    // 수정 페이지
    const {
      data: groupData,
      isError: isGroupError,
      isLoading: isGroupLoading,
    } = useQuery(
      ['recruitDetail', groupId],
      () => fetchReadingGroupInfo(groupId as string),
      {
        staleTime: Infinity,
      },
    );

🔎 데이터 전달 없이 전달 받기 2

  • 독서 모임 수정 페이지에서 데이터를 prefetch 하는 방법
    • 현재 Next.js를 사용하기 때문에 getServerSideProps를 통해 상세 데이터를 모임 페이지가 render 되기 전에 pre-fetch 하는 방법이다.
      export const getServerSideProps: GetServerSideProps = async (
        context: GetServerSidePropsContext,
      ) => {
        const queryClient = new QueryClient();
        const {
          query: { groupId },
        } = context;
        // query ker가 ['recruitDetail', groupId]인 query에 data pre-fetch
        // 만약 수정 페이지에서 pre-fetch된 데이터가 없을 경우 staleTime을 설정해주어야 함
        await queryClient.prefetchQuery(['recruitDetail', groupId], () =>
          fetchReadingGroupInfo(groupId as string),
        );
        // queryClient 객체의 상태를 직렬화한 후, props 객체에 dehydratedState 속성으로 할당
        return {
          props: {
            dehydratedState: dehydrate(queryClient),
          },
        };
      };
    • TanStack Query의 queryClient.prefetchQuery와 Next.js의 getServerSideProps를 통해 데이터를 pre-fetch 할 수 있다.
    • 페이지의 데이터가 자주 바뀌지 않으면 getStaticProps를 고려해보면 좋을 것 같다!
    • TanStack Query로 SSR 하는법

📌 방법 별 장단점 및 내가 캐싱된 데이터를 사용하는 방법을 선택한 이유

🔎 장단점

  • useRouter push 함수의 객체 필드 query 사용
    • 장점 => query 필드의 value로 전달할 데이터만 설정하기만 하면 됨
    • 단점 => query로 전달하기에는 무거운 데이터, query를 통해 여러개의 데이터를 전달하는 방법은 url 가독성 저하 및 브라우저에 길이 제한이 있을 때 또 다른 문제를 발생시킬 수 있다.
  • 독서 모임 상세 페이지에서 캐싱된 데이터를 사용하는 방법
    • 장점 => 상세 페이지에서 캐싱한 데이터를 그대로 가져와서 사용하기 때문에 fetch 없이 데이터를 사용할 수 있음
    • 단점 => 현재 까지는 큰 단점은 파악하지 못했는데 위에서 언급했듯이 여러 상황을 고려해보며 찾아내야 할 것 같다.
  • 독서 모임 수정 페이지에서 데이터를 prefetch 하는 방법
    • 장점 => 데이터를 fetch 하기 때문에 캐싱된 데이터를 사용하는 방법보다 데이터 불 일치 확률히 현저히 낮을 것이다.
    • 딱히 큰 단점은 없지만 fetch를 한번 더 한다는 점에서 캐싱된 데이터를 사용하는 방법보다 성능이 떨어질 확률이 있을 것 같다.

🔎 내가 캐싱된 데이터를 사용하는 방법을 선택한 이유

  • 현재 수정 페이지는 상세 페이지에 종속되어 있다고 생각한다. 그러므로 상세 페이지에서 데이터 fetch, re-fetch, 수정 등의 작업이 발생해도 캐싱된 상세 페이지 데이터를 수정 페이지가 사용할 수 있기 때문에 해당 방법을 선택했다.
  • prefetch하는 방법에 있어 한번 더 fetch 한다는 사실 때문에 도입을 하지 않았다. 만약 성능에 차이가 없고 현재 사용하는 방법이 데이터 불 일치 문제가 있을 경우 prefetch를 고려해봐도 좋을 것 같다.

📌 결론

  • 데이터 fetch 없이 이전 데이터를 반영하고 있다!(화질이 안좋습니다 ㅠㅠ)
  • 작업을 마무리하고 돌아보니 작업의 시작과 끝이 UX 향상이였던 것 같다. 수정 페이지에 이전 데이터 반영해야 하는 이유, 이전 데이터를 반영하는 방법 중에 어떤 방법이 좋은 성능을 보장할까등의 질문을 나 자신과 팀원들에게 던지며 작업을 진행했다. 그 과정에서 기술 뿐만 아니라 여러 상황을 고려해야 사용자가 조금 더 편할 수 있다는 사실을 알 수 있었다.
  • 부족하거나 잘못된 부분이 있으면 피드백 부탁드립니다!

0개의 댓글