
맛집 리스트 페이지는 네비게이션바에서 '# 맛집 리스트'를 통해 이동할 수 있는 페이지이다. 맛집 데이터들을 이대 정문, 이대 후문, 신촌 으로 세분화하여 맛집 위치에 따라 보여준다.
한 화면에는 3개의 맛집만 보여주며, 페이지네이션을 구현하여 페이지를 이동할 수 있도록 구현했다.
let [tab, setTab] = useState(0); // 0 정문, 1 후문, 2 신촌
<ListPlace01
tab={tab}
onClick={() => {
setTab(0);
}}
>
이대 정문
</ListPlace01>
<ListPlace02
tab={tab}
onClick={() => {
setTab(1);
}}
>
이대 후문
</ListPlace02>
<ListPlace03
tab={tab}
onClick={() => {
setTab(2);
}}
>
신촌
</ListPlace03>
위 코드는 맛집 위치 카테고리를 선택할 수 있는 라벨을 구현한 코드이다. 맛집 위치를 클릭할 때마다 tab 의 값이 달라져서 위치에 따라 맛집 리스트를 화면에 보여준다.
리액트의 useState 를 사용해서 setTab 함수를 통해 state 를 변경할 수 있다.
데이터베이스로 firebase 를 사용했기 때문에 맛집 리스트 데이터를 firestore의 컬렉션에서 가져와야 한다.
편의를 위해 이대 정문에 대한 코드만 설명하고자 한다.
이대 정문 맛집에 대한 데이터는 place01 컬렉션에 있으므로, 컬렉션에 접근할 때 사용할 변수 ref 값을 다음과 같이 할당한다.
const ref = db.collection("place01");
또한, firestore의 데이터를 리스트 형식으로 불러오기 위해서는 getData() 함수가 필요하다. firestore에서 가져온 데이터를 doc.data() 와 push 함수를 이용해 item 배열에 넣은 다음, 이를 다시 setPlace01Data 에 담아 리스트 페이지에 출력하였다.
const [items, setItems] = useState(3);
const [page, setPage] = useState(1);
const handlePageChange = (page) => {
setPage(page);
};
let navigate = useNavigate();
function getData() {
ref.onSnapshot((querySnapshot) => {
const items = [];
querySnapshot.forEach((doc) => {
items.push(doc.data());
});
setPlace01Data(items);
setLoader(false);
});
}
useEffect(() => {
getData();
}, []);
다음은 페이지네이션을 구현한 부분이다.
$ npm install react-js-pagination
라이브러리를 사용했기 때문에 설치가 필요하다.
return (
<>
<Container>
<ListName>이대 정문 맛집</ListName>
<ContentsWrap>
{loader === false &&
place01data
.slice(items * (page - 1), items * (page - 1) + items)
.map((v, i) => {
return (
<div key={i}>
<DataContainer
onClick={() => {
navigate(`/listdetail01/${i + (page - 1) * 3}`);
}}
>
<ListPageRow>
<Col1>
<MainIMG src={v.url} />
</Col1>
<Col2>
<RestName>{v.name}</RestName>
<MapPinIMG src={mappin} />
<InfoText>{v.addr}</InfoText>
<ClockIMG src={clock} />
<InfoText>{v.time}</InfoText>
<HeartIMG src={heartt} />
<InfoText>대표 메뉴 - {v.bestmenuname}</InfoText>
</Col2>
</ListPageRow>
</DataContainer>
<Border />
</div>
);
})}
</ContentsWrap>
<Pagination
activePage={page}
itemsCountPerPage={items}
totalItemsCount={place01data.length - 1}
pageRangeDisplayed={5}
onChange={handlePageChange}
></Pagination>
</Container>
</>
);
}
음식점의 정보들을 페이지별로 구분해서 보여주기 위해 배열을 잘라주는 slice 함수를 사용하였다.
다음은 map 함수를 통해 반복되는 컴포넌트들을 렌더링 해주었다.
key 값을 i로 설정해주었는데, 키값은 컴포넌트를 렌더링 하였을 때 어느 item이 변경되는지 빠르게 감지하기 위해 사용한다. 여기서 key값은 요소의 고유한 값이어야 한다.