마켓컬리 메인 페이지에서 MD 추천은 카테고리 버튼을 클릭할 때마다 해당 카테고리 내 추천 제품이 보여진다. 여기에서 고민이 시작되었는데...
우선 동일한 페이지에서 구현되어 URL 변화는 없고, 그렇기 때문에 동적 라우팅을 적용하는 것은 아니라고 판단했다.
여기서 두 가지 가설을 세웠는데, 1) 카테고리 버튼을 클릭할 때마다 해당 카테고리의 index를 post하고 그에 맞는 데이터(추천 제품)을 받아와 컴포넌트에 담아준다. 2) 모든 버튼에 해당하는 데이터를 받아오고 클릭된 버튼에 맞는 데이터만 필터링한다.
하지만 아무리 생각해도 2번 가설은 너무 많은 데이터를 받아오기 때문에 적합하지 않을 것 같고, 개발자 도구 network에서 버튼을 클릭할 때마다 통신이 일어난다는 것을 확인할 수 있었다.
결국 1번 가설이 맞다는 판단이 들었다.
해결책을 찾는 중... 아주 딱 맞는 타이밍에 Pagination 세션을 듣게 되었다 야호!🙌
서버에서 오는 데이터를 원하는 길이로 끊어서 전달 받을 수 있는 기능이 바로 페이지네이션이다. 웹에서 흔하게 볼 수 있는 page 1,2,3,4,,,를 구현하기 위한 기능이다.
그렇다면 처음 세웠던 가설과 같이 클릭한 카테고리에 대한 정보를 백엔드에 전달해야하는데 이는 쿼리 스트링(Query String)을 사용하면 된다.
A query string is a part of a uniform resource locator (URL) that assigns values to specified parameters. A query string commonly includes fields added to a base URL by a Web browser or other client application, for example as part of an HTML form [출처_wikipedia]
페이지네이션을 위해서는 쿼리 스트링에 limit와 offset을 포함시켜주어야 한다.
우리 팀의 경우 하나의 카테고리 당 6개의 추천제품을 보여주기로 했기 때문에 limit=6이고 각 카테고리마다 동일한 값이기 때문에 변수로 지정해주었다. const LIMIT = 6;
사용자가 원하는 카테고리 버튼을 클릭하면 카테고리에 해당하는 ListCategory 컴포넌트에서 onClick 이벤트를 통해 handleColor 함수가 실행된다. (함수명을 handleColor로 설정한 이유는 클릭될 때마다 회색에서 보라색으로 백그라운드 컬러가 변경되어야 하기 때문!)
클릭을 했을 때 1) 버튼 색상 변경, 2)해당되는 카테고리 추천 제품 데이터 불러오기, 두 가지 이벤트를 실행하고 싶기 때문에 handleColor 함수 안에 handleCategory 함수(2번에 해당)를 넣어주었다.
먼저 1번부터 살펴보자면, 처음 웹이 로딩되었을 때 디폴트로 채소가 클릭되었으면 해서 state 값으로 clickIndex='1'
을 설정해주었다. 버튼을 클릭하면 함수가 실행되고, 클릭된 data-idx로 clickIndex가 재 설정된다.
그렇게 된다면 삼항연산자에서 clickIndex가 index+1 값과 동일해져 true가 되고 className이 clicked로 변경된다. scss에서 클래스 별로 다른 배경 색을 적용했기 때문에 클릭된 버튼의 색상이 바뀌게 된다.
비표준 속성, dataset [출처_javascript.info]
비표준 속성은 사용자가 직접 지정한 데이터를 HTML에서 자바스크립트로 넘기고 싶은 경우나 자바스크립트를 사용해 조작할 HTML 요소를 표시하기 위해 사용할 수 있다.
data-
로 시작하는 속성 전체는 개발자가 용도에 맞게 사용하도록 별도로 예약된다.dataset
프로퍼티를 사용하면 이 속성에 접근할 수 있다.
id가 3인 카테고리를 클릭한 경우, /product/mdrecommendation?limit=6&offset=18
페이지네이션이라는 개념을 접하기 전, 어떤 방식으로 데이터가 들어오고 출력될지 고민하고 그에 대한 해결책을 찾아 나갔다는 점에서 개인적으로 기억에 가장 남는 기능 구현이였다. 카테고리 별 정보 전달이라는 웹의 가장 기본적인 기능인 만큼 앞으로도 유용하게 활용할 것 같다!🤓