책 형태의 네비게이션 효과 - 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 값을 인자로 받아 해당 페이지로 이동합니다.

요약

  1. SnackTag 컴포넌트 : 태그 버튼을 클릭하면 onButtonClick 함수가 호출되어 해당 페이지 인덱스를 SnackInfoView 컴포넌트로 전달합니다.
  2. SnackInfoView 컴포넌트 : SnackTag에서 전달받은 페이지 인덱스를 SnackList 컴포넌트로 전달합니다.
  3. SnackList 컴포넌트 : pageIndex 상태가 변경될 때마다 해당 페이지로 이동합니다.