배워서 남 주자

상세 페이지에서 뒤로가기 클릭시 원래 있던 목록 페이지로 돌아가기

미래에서 온 개발자 2024. 4. 23. 20:32

목록 페이지에 페이지네이션이 있을 때, 상세 페이지를 갔다가 뒤로 가기를 눌렀을 때 항상 1페이지로 돌아가는 것이 아니라 원래 있던 페이지를 기억해서 해당 페이지로 돌아오게 하는 기능을 구현하는 방법을 간략하게 정리해 본다.

 

위의 기능을 구현하기 위해서는 현재 페이지를 어딘가에 저장해두어야 하는데 이때 다음의 세 가지 방식을 생각해 볼 수 있을 것 같다.

 

1. 브라우저의 sessionStorage 

세션 스토리지는 탭이 열려 있는 동안 정보를 저장할 수 있어, 사용자가 페이지를 떠났다가 돌아왔을 때 이전 페이지 정보를 유지하는 데 유용하다. 

 

2. URL의 쿼리 스트링 

URL로부터 페이지 정보를 읽어들일 수 있다. URL을 가지고 있으면 탭을 닫았다가 다시 열 때도 이전 페이지로 돌아갈 수 있고, 해당 URL을 다른 사람과 공유할 수도 있다는 장점이 있다. 

 

3. react router의 상태 관리 기능 

히스토리 스택 관리도 같이 생각해줘야 한다. 

 

 

이 포스팅에서는 URL 쿼리 스트링으로 현재 페이지를 기억하는 방식으로 구현해 보고자 한다. 구현 방식은 아래와 같다.

 

먼저 쿼리 스트링을 보다 쉽게 다루기 위해서 URLSearchParams을 사용해 custom hook을 작성해 주었다.    

import { useLocation, useNavigate } from 'react-router-dom';

export function useQueryString() {
  const { search } = useLocation();
  return new URLSearchParams(search);
}

export function useUpdateQueryString() {
  const navigate = useNavigate();
  const { search, pathname } = useLocation();

  return (key: string, value: string | number | undefined | null) => {
    const params = new URLSearchParams(search);

    if (value === undefined || value === null || value === '') {
      params.delete(key);
    } else {
      params.set(key, value.toString());
    }

    navigate(`${pathname}?${params.toString()}`, { replace: true });
  };
}

 

 

그 다음으로 pagination 상태를 반환하는 custom hook을 작성했다. (프로젝트 내에서 antd를 사용하고 있다.)

currentPage가 바뀔 때마다 useEffect가 실행되어 pagination.current 값이 업데이트된다. 

import { useState, useEffect } from 'react';
import { useQueryString } from '@/utils/urlQueryParams';
import type { TablePaginationConfig } from 'antd';

export const usePagination = (defaultPageSize: number = 10) => {
  const queryString = useQueryString();
  const currentPage = Number(queryString.get('page')) || 1;
  const [pagination, setPagination] = useState<TablePaginationConfig>({
    current: currentPage,
    pageSize: defaultPageSize,
  });

  useEffect(() => {
    setPagination((prev) => ({
      ...prev,
      current: currentPage,
    }));
  }, [currentPage]);

  return pagination;
};

 

 

사용자가 페이지네이션의 번호나 이전 페이지, 다음 페이지 등을 클릭할 때 작성해둔 useUpdateQueryString을 호출해 다음과 같이 사용한다.

const updateQueryString = useUpdateQueryString();

// 이벤트 핸들러 콜백에서 다음과 같이 함수를 호출
updateQueryString('page', pagination.current);

 

페이지 뿐만 아니라 탭을 기억해서 돌아와야 할 때에도 다음과 같이 onChange 콜백에서 updateQueryString을 호출할 수 있다.

const onChange = (key: string) => {
  updateQueryString('tab', key);
};