TIL/Project

[React] 스크롤 시 나타나는 위로 가기 버튼 구현

시럽이 2022. 7. 25. 17:45

이전에 <[클론코딩] Footer layout 구현 완료> 포스팅에서 아래와 같은 코드를 작성했었는데

<button className="btnForUp" onClick={goTop} onScroll={fadeBtn}>
	<img src="/images/Footer/up-arrow.png" alt="up" />
</button>

// 부드러운 스크롤
const goTop = () => {
  window.scrollTo({
    top: 0,
    left: 0,
    behavior: 'smooth',
  });
};

// 스크롤 시 나타나는 버튼
const fadeBtn = () => {
  if (
    document.body.scrollTop > 200 ||
    document.documentElement.scrollTop > 200
  ) {
    document.getElementsByClassName('btnForUp')[0].style.right = '0';
  } else {
    document.getElementsByClassName('btnForUp')[0].style.right = '-50px';
  }
};
 

[클론코딩] Footer layout 구현 완료

푸터는 거의 퍼블리싱 위주여서 수월하게 진행했다. 장바구니하다가 푸터하니 정말 단순 작업처럼 느껴졌다. 클론코딩한 사이트의 푸터가 우리가 메인 폰트로 정한 'Gowun Dodum'보다는 고딕체에

syrup-log.tistory.com

DOM에 직접 접근하는 방식은 지양하고, useRef/useState hook 활용 + 동적인 className으로 구현하라는 멘토님의 리뷰를 받았다. 자바스크립트와 리액트 함수는 100% 같을 수 없다는 것을 다시금 깨달으며... useRef에 대한 개념을 처음 알았고, 이 부분에 대해 공부한 내용은 따로 정리하고자 한다.

 

 

하지만 구글링하고 2-3시간씩 머리를 싸매고 고민해봐도 useRef를 사용했을 때 에러가 발생해서

useState와 useEffect를 사용해서 내가 원하는 화면을 구현할 수 있었다.

Footer에서는 따로 함수가 필요 없어서 '위로 가기 버튼'을 구현하기 위한 컴포넌트를 따로 만들어주었다.

<BtnForUp />

 

const BtnForUp = () => {
  const [scrollY, setScrollY] = useState(0);
  const isBtnActive = scrollY > 200;

  const fadeUpBtn = () => {
    setScrollY(window.pageYOffset);
  };

  const scrollingToTop = () => {
    window.scrollTo({
      top: 0,
      behavior: 'smooth',
    });
    setScrollY(0);
  };

  useEffect(() => {
    window.addEventListener('scroll', fadeUpBtn);

    return () => {
      window.removeEventListener('scroll', fadeUpBtn);
    };
  }, []);

  return (
    <button
      className={isBtnActive ? 'btnForUp active' : 'btnForUp'}
      onClick={scrollingToTop}
    >
      <img src="/images/Footer/up-arrow.png" alt="up" />
    </button>
  );
};

그렇게 스크롤 시 위로 가기 버튼 나타나기 + 상단으로 부드러운 스크롤을 만든 최종 결과물은 위와 같다. DOM에 직접 접근하지 않고 어떻게 코드를 짜야 하는지 멘토님께 달려가고 싶은 순간이 한두번이 아니었는데 인내심을 가지고 구글링한 덕에 좋은 레퍼런스를 찾을 수 있었던 것 같다.😰

 

 

 

 

참고

https://wazacs.tistory.com/21