책 형태의 네비게이션 효과 - Part3 태그 검색 기능 추가
ㆍProject Diary/React + Firebase (Snack ShoppingMall)
책 형태의 네비게이션에서 태그를 통해 해당 페이지로 이동하는 기능을 추가하는 방법 기록
1. SnackTag 컴포넌트
먼저, 태그 버튼을 클릭하면 해당하는 페이지로 이동하는 기능을 구현합니다.
// 태그 버튼에 호버 애니메이션 추가
const hoverLine = keyframes`
0% {
opacity: 0;
transform: translateY(100%);
}
50% {
opacity: 1;
transform: translateY(0%);
}
100% {
opacity: 0;
transform: translateY(100%);
}
`;
// SnackTag 컴포넌트 정의
const SnackTag = ({ onButtonClick }) => {
// 태그 버튼 클릭 시 호출되는 함수
const handleClick = (pageIndex) => {
onButtonClick(pageIndex);
};
return (
<SnackTagBlock>
<button onClick={() => handleClick(0)}>도넛류</button>
<button onClick={() => handleClick(6)}>과자류</button>
<button onClick={() => handleClick(12)}>빵류</button>
<button onClick={() => handleClick(18)}>디저트류</button>
</SnackTagBlock>
);
};
export default SnackTag;
이 코드에서는 SnackTag라는 컴포넌트를 정의했습니다.
태그 버튼을 클릭하면 onButtonClick 함수가 호출되어 해당 페이지 인덱스를 전달합니다.
2. SnackInfoView 컴포넌트에 태그 기능 추가
이제 SnackInfoView 컴포넌트에 SnackTag 컴포넌트를 포함시키고, 태그 클릭 시 페이지를 변경하는 로직을 추가합니다.
import React, { useState } from "react";
import styled from "styled-components";
import SnackSearch from "@/components/snackInfo/SnackSearch";
import SnackList from "@/components/snackInfo/SnackList";
import SnackTag from "@/components/snackInfo/SnackTag";
const SnackInfoViewBlock = styled.div``;
// SnackInfoView 컴포넌트 정의
const SnackInfoView = () => {
// 페이지 인덱스 상태
const [pageIndex, setPageIndex] = useState();
// 검색어 상태
const [searchKeyword, setSearchKeyword] = useState("");
// 태그 버튼 클릭 시 호출되는 함수
const handleButtonClick = (index) => {
setPageIndex(index);
};
// 검색어 입력 시 호출되는 함수
const onSearch = (keyword) => {
setSearchKeyword(keyword);
};
return (
<SnackInfoViewBlock>
<SnackSearch onSearch={onSearch} />
<SnackTag onButtonClick={handleButtonClick} />
<SnackList pageIndex={pageIndex} searchKeyword={searchKeyword} />
</SnackInfoViewBlock>
);
};
export default SnackInfoView;
3. SnackList 컴포넌트에 태그 검색 기능 추가
마지막으로 SnackList 컴포넌트에서 pageIndex 상태를 받아 페이지를 변경하는 로직을 추가합니다.
useEffect(() => {
if (pageIndex !== undefined && currentPageIndex !== pageIndex) {
setCurrentPageIndex(pageIndex);
setTimeout(() => {
pageFlipRef.current.pageFlip().flip(pageIndex);
}, 500);
}
}, [pageIndex, currentPageIndex]);
이 코드는 태그 버튼을 클릭하여 pageIndex가 변경되면, 현재 페이지 인덱스를 업데이트하고, pageFlip 라이브러리를 사용하여 해당 페이지로 이동하는 기능을 구현합니다.
이를 통해 사용자는 태그를 클릭할 때 원하는 페이지로 부드럽게 이동할 수 있습니다.
위 코드에서 각 부분을 자세히 설명하겠습니다.
useEffect 훅 사용
- useEffect는 리액트 컴포넌트가 렌더링된 이후에 수행되는 사이드 이펙트를 처리하기 위해 사용됩니다.
- 이 경우에는 pageIndex나 currentPageIndex가 변경될 때마다 특정 로직을 수행합니다.
의존성 배열 : [pageIndex, currentPageIndex]
- 이 배열에 있는 값들이 변경될 때마다 useEffect 내부의 함수가 실행됩니다.
조건문
if (pageIndex !== undefined && currentPageIndex !== pageIndex)
- pageIndex가 undefined가 아니고 currentPageIndex와 pageIndex가 다를 때만 내부 로직을 실행합니다.
- pageIndex가 undefined일 경우를 체크하는 이유는 컴포넌트가 처음 렌더링될 때 pageIndex가 아직 설정되지 않았을 수 있기 때문입니다.
- currentPageIndex와 pageIndex가 다를 때만 페이지를 변경해야 하기 때문에 이를 체크합니다. 같을 경우에는 불필요한 페이지 변경을 방지합니다.
상태 업데이트
setCurrentPageIndex(pageIndex);
- currentPageIndex 상태를 pageIndex로 업데이트합니다. 이렇게 하면 현재 페이지 인덱스를 최신값으로 유지할 수 있습니다.
페이지 이동
setTimeout(() => {
pageFlipRef.current.pageFlip().flip(pageIndex);
}, 500);
- setTimeout을 사용하여 500밀리초 후에 페이지를 이동합니다.
- pageFlipRef.current.pageFlip().flip(pageIndex)는 pageFlip 라이브러리를 사용하여 페이지를 실제로 변경하는 함수입니다. pageIndex 값을 인자로 받아 해당 페이지로 이동합니다.
요약
- SnackTag 컴포넌트 : 태그 버튼을 클릭하면 onButtonClick 함수가 호출되어 해당 페이지 인덱스를 SnackInfoView 컴포넌트로 전달합니다.
- SnackInfoView 컴포넌트 : SnackTag에서 전달받은 페이지 인덱스를 SnackList 컴포넌트로 전달합니다.
- SnackList 컴포넌트 : pageIndex 상태가 변경될 때마다 해당 페이지로 이동합니다.