SPA에서 filter, pagination 구현하기

김현조·2023년 4월 5일
15

FrontEnd

목록 보기
7/9

많은 웹사이트들은 게시물이나 문제 등을 기준에 따라 필터링하고, 페이지를 넘기며 확인할 수 있도록 구현하고 있다. 예를 들어 아래와 같이 좌측에서는 “풀이 여부”, “카테고리” 등의 필터를 통해 문제를 검색하고, 하단에서는 페이지 번호를 통해 여러 페이지로 구성하는 흔한 방식이다.

하지만 이러한 필터와 페이지네이션을 사용하는 많은 SPA 페이지들은 각자의 특성에 맞는 구현 방식을 취하고 있으며 크게 두가지로 나누어볼 수 있다.

  1. 새로고침시 상태가 유지되지 않는 페이지
  2. 새로고침시 상태가 유지되는 페이지

이는 다시 말해 필터, 페이지 정보를 SPA내 상태로 처리하는지, 브라우저 저장소 등을 활용해 저장하는지에 따른 차이를 의미한다. 전자의 경우 React의 state등을 활용해볼 수 있고, 후자의 경우 아래와 같은 선택지가 자주 사용된다.

  • 브라우저 저장소
    • local storage: 페이지 닫아도 유지
    • session storage: 페이지 닫으면 삭제
  • URL Parameter (query parameter)

(위의 이미지 내 사이트)[https://csbroker.io/problem]는 초기에 전자의 방식이었으나 유저 입장에서 필터 정보가 뒤로가기, 새로고침 등 이후에도 유지될 것이라 예상되는 경우가 많았기 때문에 후자의 방식으로 변경했다.

이때 parameter가 변경될때마다 api요청을 보내야하기 때문에, 필터와 페이지 정보를 params라는 state를 생성하여 담고, react-query useQuery 훅의 queryKey에 params를 추가해주었다.

하지만 params가 state로 생성되었을 때의 문제점이 있다. params가 처음 세팅되면서 쿼리가 두번 나가게 된다는 사실이다. 따라서 params의 값이 존재하지 않을 때는 쿼리 요청을 하지 않기 위해 useQuery의 옵션을 enabled: !!params 로 설정했다. 그 결과는 다음과 같다.

const [params, setParams] = useState<IProblemRequestParam>();

const { data } = useQuery<IProblemListResponseData>(
    [QUERY_KEY.PROBLEM_LIST, params],
    () => problemApiWrapper.problemList({ ...params, size: 12 }),
    { enabled: !!params },
  );

useEffect(() => {
    setParams({ ...getFilterParams(checkedTags), page: page });
  }, [checkedTags, page]);

또한 페이지의 경우 url에 직접 입력해도 이동되도록 url parameter로 설정했다. 태그의 경우에는 페이지를 닫아도 유지될 수 있도록 local storage에 저장했지만, 유저 피드백을 통해 페이지를 다시 열었을 때도 태그가 유지되는 것이 어색하다는 의견에 따라 session storage를 활용했다.

이러한 과정에서 다른 웹페이지들은 비슷한 상황을 어떻게 구현할까?

비슷한 사이트인 프로그래머스의 경우에는 페이지와 태그를 모두 url search parameter에 설정하여 유지한다.

더불어 태그와 정렬 기준을 local storage에 저장하여 다시 접속해도 해당 정보가 유지되도록 구현하고 있다.

구글의 경우에는 검색어는 명확하게 url search parameter에 넣지만, 다른 정보는 인코딩되어있어서 직관적으로 읽기는 어려웠다.

Github의 경우 필터와 페이지를 모두 url search parameter에 저장했다.

대부분의 사이트에서 해당 데이터를 모두 url search param에 넣는다는 것을 알 수 있었다. 뒤로가기, 새로고침에 대응되기 때문에 페이지를 다시 열었을 때 저장될 필요가 없다면 가장 좋은 방법인 것으로 보인다. 물론 브라우저 저장소를 이용해도 똑같은 구현이 가능하지만 상대적으로 아래와 같은 차이를 확인해보아야 한다.

브라우저 저장소는 url param에 비해…

  • 유저가 수정할 가능성이 낮다.
  • 유저에게 보이지 않는다.
  • 디버깅이 어렵다.
  • origin에 묶여있어 외부 접근이 어렵다.
  • JSON.stringify, JSON.parse를 계속 호출해야 한다.

위의 내용을 볼때 url search param과 브라우저 저장소를 함께 이용하는 것이 현재의 서비스에 적절한 것으로 생각된다.

0개의 댓글