[2022.07.28] 리액트로 컴포넌트 fade-in/out 애니메이션 넣어보기

REASON·2022년 7월 28일
1

STUDY

목록 보기
85/127

메뉴를 클릭했을 때 사이드바 메뉴가 나타나는 효과를 넣고 싶은데 어떻게 해야 되는지 몰라서 한참을 구글링했다.

첫 시도에 react-transition-group 라이브러리를 사용하려 했는데 몇시간째 붙잡고 있어도 원하는 동작이 안나와서 다른 방법을 모색했다..ㅋㅋ

두번째 시도는 useEffect로 mount, unmount 조작을 해야겠다!!했는데 이것도 역시 원하는 대로 나오지 않았다. (외않되?)

그냥 내가 못해서 두 방법 모두 안되는 거겠지만 ㅠㅠㅠㅠ
세번째 방법으로는 아예 state변수를 만들어서 이 값에 따라 css를 적용시키기로 했다.

const [showSideMenu, setShowSideMenu] = useState(false);
const [fadeInOut, setFadeInOut] = useState('');

먼저 true/false로 버튼을 눌렀을 때 사이드바가 나타나야 하므로 showSideMenu라는 state를 만들어줬다.
초기값은 아직 누르기 전 상태이니 false.
fadeInOut 변수는 className으로 부착할 클래스명이다.

const Menu = () => {
    return (
      <div className={'side-menu ' + fadeInOut}>
        <ul>
          <li>사이드 메뉴1</li>
          <li>사이드 메뉴2</li>
        </ul>
      </div>
    );
  };

그리고 이건 기능 동작이 제대로 되는지 확인이 제일 중요했기 때문에 대충 만들어 놓은 사이드메뉴 컴포넌트이다.
지금 보니 이 친구 컴포넌트 이름도 SideMenu로 바꿔주는 게 더 좋을 것 같다.ㅋㅋ

그리고 이 컴포넌트를 보여줄 부분에는 삼항 연산자를 사용했다.

{showSideMenu ? <Menu onClick={showMenuList} /> : null}

앞에 선언했던 showSideMenu가 true일 때 사이드 메뉴가 나타나야 하기 때문이다.

<li onClick={showMenuList}>Menu</li>

상단 메뉴 부분의 'Menu' 리스트를 클릭하면 사이드바가 나오도록 하고 싶기 때문에 li태그에 onClick을 부착해주었다.
showMenuList 함수는 다음처럼 동작한다.

const showMenuList = () => {
    if (showSideMenu) {
      setFadeInOut('fade-out');
      setTimeout(() => {
        setShowSideMenu(!showSideMenu);
      }, 1000);
    } else {
      setFadeInOut('fade-in');
      setShowSideMenu(!showSideMenu);
    }
  };

showSideMenu가 true값일 때 클릭했으면 사이드 메뉴가 사라져야 하므로 클래스명을 fade-out로 바꾸도록 해야하므로 setFadeInOut의 값을 'fade-out'으로 바꿔주었다.

컴포넌트가 먼저 사라져버리면 깜빡 거리는 효과로 적용돼서 setTimeout으로 약간의 시간초를 두었는데.. 이 부분에서 사라지는 시간에 지연이 생겨서 메뉴 버튼을 이때 한번 더 클릭하면 무시될 수도 있다는 버그가 있다..

일단은 동작하는데 코드는 다시 수정해야겠다..

메뉴를 클릭하면 왼쪽에 사이드바가 페이드 인 아웃되는 효과다.
사실 원래는 transform으로 왼쪽에서 사이드바가 날아오도록 하고 싶었는데 ㅋㅋ 페이드 인 아웃이 되버린건 컴포넌트에 css가 제대로 적용이 안돼서 뭐라도 해보자는 마음에 가장 흔한 걸로 넣어서 이렇게 됐다.
어차피 버그 때문에 다시 코드를 갈아야 되므로 그때 원하는 동작을 넣어보도록 해야겠다.

작성한 전체 코드

function Nav() {
  const [showSideMenu, setShowSideMenu] = useState(false);
  const [fadeInOut, setFadeInOut] = useState('');

  const showMenuList = () => {
    if (showSideMenu) {
      setFadeInOut('fade-out');
      setTimeout(() => {
        setShowSideMenu(!showSideMenu);
      }, 1000);
    } else {
      setFadeInOut('fade-in');
      setTimeout(() => {
        setShowSideMenu(!showSideMenu);
      }, 100);
    }
  };

  const Menu = () => {
    return (
      <div className={'side-menu ' + fadeInOut}>
        <ul>
          <li>사이드 메뉴1</li>
          <li>사이드 메뉴2</li>
        </ul>
      </div>
    );
  };

  return (
    <nav className="menu-container">
      {showSideMenu ? <Menu onClick={showMenuList} /> : null}
      <ul className="menu">
        <li onClick={showMenuList}>Menu</li>
        <li className="blog-title">YU TO BLOG</li>
        <li className="search-icon">search</li>
      </ul>
    </nav>
  );
}

export default Nav;

fade in-out 관련 css

.fade-in {
  opacity: 1;
  animation: fadeIn ease-in-out 1s;
}

.fade-out {
  opacity: 0;
  animation: fadeOut ease-in-out 1s;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@keyframes fadeOut {
  0% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

넘모 어려운 리액트..
바닐라 자바스크립트 코드 넣고 싶은 마음에 뿜뿜했다.
왜 CSS도 내 마음대로 못 넣는데??!?!ㅋㅋㅋㅋ ㅠㅠㅠ

0개의 댓글