[문제 해결] - 데이터 개수에 따른 페이지네이션 컴포넌트 조건부 렌더링

Donggu(oo)·2023년 4월 28일
post-thumbnail

1. 문제 현상


  • 첫 번째 페이지가 아닌 다른 페이지의 다이어리 글을 본 후 다시 뒤로 가기로 마이페이지로 돌아오면 해당 다이어리가 있는 페이지 순서가 아닌 첫 번째 페이지네이션 컴포넌트로 가 있는 현상을 발견했다.

  • 그리고 나의 다이어리에서 다른 페이지의 글을 보다가 좋아한 다이어리나 작성한 댓글 탭으로 이동하면 페이지네이션 컴포넌트가 해당 글이 있는 위치가 아닌 이상하게 보이는 현상도 있었다.

2. 문제 원인


  • 일단 2가지 문제의 원인을 가만히 생각해 보니 공통적으로 1부터 5페이지가 있는 첫 번째 페이지에서는 문제가 발생하지 않았다. 6부터 이후의 페이지에서 이동이 발생할 경우 페이지네이션 컴포넌트가 제 위치를 못 찾고 이상해지고 있었다.

  • 현재 다이어리를 본 후 뒤로 가기를 해도 첫 번째 페이지로 돌아가는 게 아닌 해당 다이어리가 있는 페이지가 있는 위치로 돌아가도록 탭과 페이지 번호를 로컬 스토리지에 저장해두고 있는 상태였다.

  • 그래서 로컬 스토리지를 보면서 디버깅 중 탭의 상태는 myCurrentTab, 페이지의 상태는 myCurrentPage 하나로 나의 다이어리, 좋아한 다이어리, 작성한 댓글이 상태를 모두 공유하고 있다는 것을 발견했다.

  • 즉, 나의 다이어리에서 11번째 페이지에 있는 상태에서 좋아한 다이어리 탭으로 이동하면 좋아한 다이어리도 11이란 상태를 불러오고 있는데 좋아한 다이어리의 데이터는 2 페이지밖에 없으니 이런 현상이 발생하고 있었던 것이다...

const [myCurrentTab, setMyCurrentTab] = useState<number>(
  () => JSON.parse(window.localStorage.getItem("myCurrentTab")!) || 0
);
const [myCurrentPage, setMyCurrentPage] = useState<number>(
  () => JSON.parse(window.localStorage.getItem("myCurrentPage")!) || 1
);
  
useEffect(() => {
  window.localStorage.setItem("myCurrentTab", JSON.stringify(myCurrentTab));
}, [myCurrentTab]);

useEffect(() => {
  window.localStorage.setItem("myCurrentPage", JSON.stringify(myCurrentPage));
}, [myCurrentPage]);

3. 문제 해결


1) 1차 시도 : 탭 이동 시 페이지를 1페이지로 변경해본다.

  • 우선 1차적으로 탭 이동 시 myCurrentPage의 상태를 1로 초기화 시켜주면 될 것 같다는 생각이 들었다.
useEffect(() => {
  window.localStorage.setItem("myCurrentTab", JSON.stringify(myCurrentTab));
  setMyCurrentPage(1);  // 페이지를 1로 초기화
}, [myCurrentTab]);
  • 수정 후 다시 확인해 보니 state가 변경될 때마다 리렌더링이 일어나 상태가 초기화되면서 다이어리를 확인 후 뒤로 가기를 하면 해당 다이어리가 있는 페이지로 이동해야 하는데 제일 첫 번째 페이지로 이동해버렸다.

2) 2차 시도 : 페이지 변경 발생 시 해당 페이지로 상태값을 변경해본다.

  • 페이지 변경 시에는 해당 페이지로 상태를 변경해 보았지만 이번에는 해당 다이어리가 있는 페이지로는 돌아왔지만 페이지네이션 컴포넌트가 첫 번째 페이지가 있는 곳으로 돌아와 있었다.
useEffect(() => {
  window.localStorage.setItem("myCurrentTab", JSON.stringify(myCurrentTab));
  setMyCurrentPage(1);  // 페이지를 1로 초기화
}, [myCurrentTab]);

useEffect(() => {
  window.localStorage.setItem("myCurrentPage", JSON.stringify(myCurrentPage));
  setMyCurrentPage(myCurrentPage);  // 페이지 변경
}, [myCurrentPage]);

3) 3차 시도 : 페이지 블록도 로컬스토리지에 저장한다.

  • 페이지 탭과 번호에 정신이 팔려서 놓치고 있었던 부분이 있었는데 페이지 탭과 번호만 로컬 스토리지에 저장해두고 페이지 블록은 저장하고 있지 않고 있다는 것을 늦게 깨달았다.

  • 그래서 현재 페이지 블록 상태는 하위 컴포넌트인 MypagePagination에 있었는데 이 상태를 페이지 탭과 번호 상태가 있는 상위 컴포넌트인 MypageMain 컴포넌트로 이동시킨 후 로컬 스토리지에 저장했다.

  • 마찬가지로 탭 변경 발생 시 페이지 블록을 첫 번째 블록으로 변경하고, 페이지 변경 발생 시 해당 블록으로 변경되도록 수정했다.

const [myCurrentTab, setMyCurrentTab] = useState<number>(
  () => JSON.parse(window.localStorage.getItem("myCurrentTab")!) || 0
);
const [myCurrentPage, setMyCurrentPage] = useState<number>(
  () => JSON.parse(window.localStorage.getItem("myCurrentPage")!) || 1
);
const [blockNum, setBlockNum] = useState<number>(
  () => JSON.parse(window.localStorage.getItem("myCurrentPageBlock")!) || 0
); // 현재 페이지네이션 블록 index
  
useEffect(() => {
  window.localStorage.setItem("myCurrentTab", JSON.stringify(myCurrentTab));
  setMyCurrentPage(1);
  setBlockNum(0);  // 탭 변경 발생 시 첫번째 페이지 블록으로 변경
}, [myCurrentTab]);

useEffect(() => {
  window.localStorage.setItem("myCurrentPage", JSON.stringify(myCurrentPage));
  setMyCurrentPage(myCurrentPage);
  setBlockNum(blockNum);  // 페이지 블록 변경
}, [myCurrentPage]);

// 로컬스토리지에 페이지 블록 상태도 저장
useEffect(() => {
  window.localStorage.setItem("myCurrentPageBlock", JSON.stringify(blockNum));
}, [blockNum]);
  • 이렇게 수정했더니 마침내 문제가 해결되었다. 탭을 이동할 때마다 첫 번째 페이지 블록으로 정상적으로 변경되고 다이어리 확인 후 뒤로 가기를 해도 해당 다이어리가 있는 페이지로 잘 돌아오고 있다.

  • 페이지네이션 컴포넌트를 각 페이지의 데이터 개수에 따라 조건부 렌더링으로 다르게 보여줘야 하다 보니 이런 디테일한 로직을 제대로 확인해 보지 못했었던 것 같다.

profile
FE Developer

0개의 댓글