본문 바로가기
📍 DEV/React & Next.js

useRef & scrollIntoView

by briee 2021. 11. 20.

헤더를 클릭했을 때 해당 컴포넌트로 이동하는 것을 구현하고 싶었다. 그래서 useRef와 scrollIntoView 사용하여 구현하였다. 설명보다는 간단히 기록만 하고 넘어가려 한다.

 


 

✔️ useRef

특정 DOM을 선택해야 할 때, vanilla JS에서는 getElementById, querySelector 같은 DOM Selector를 사용했다면, 리액트의 함수형 컴포넌트에서는 useRef를 사용한다. 그리고 useRef로 관리하는 변수는 값이 변경되어도 컴포넌트를 리렌더링 시키지 않는다는 특징이 있다.

 

 

✔️ element.scrollIntoView()

특정 엘리먼트가 있는 위치로 스크롤을 이동시킬 수 있다. 아래와 같이 세 가지 방법으로 사용할 수 있는데 보통 option 객체를 넣어서 사용한다. 옵션은 behavior, block, inline이 있는데 나는 body에 이미 scroll-behavior: smooth; 를 주었기 때문에 따로 사용하지는 않았다. 

element.scrollIntoView();
element.scrollIntoView(alignToTop); // Boolean parameter
element.scrollIntoView(scrollIntoViewOptions); // Object parameter
-mdn

참고: mdn

 

 

✔️ code

나는 project는 라우터를 분리했기에 메인에서는 메인섹션과 스킬섹션으로 나누어 페이지를 구성하려 했다. 만들면서 헤더의 경우 수정할 가능성이 높아서 자세한 설명은 하지 않고, 오늘 우선 구현한 코드는 이렇다. 참고로 언어 변경 버튼은 미리 구현해놔서 오늘 코드에도 함께 포함되어 있다. 그리고 알아보기 쉽게 블로그에는 컨테이너를 빼고는 className을 지워 놓았다.

 

//Main.tsx
import { useRef } from "react";
import { useTranslation } from "react-i18next";
import Header from "components/common/Header";
import Skil from "components/Skil";

const Main = () => {
  const { t } = useTranslation();
  const scrollRef = useRef<HTMLElement>(null);

  return (
    <div className="main-container">
      <Header refs={scrollRef} />
      <section>
        <div>{t("About.0")}</div>
      </section>
      <section ref={scrollRef}>
        <Skil />
      </section>
    </div>
  );
};

export default Main;

 

//Header.tsx
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import LangBtn from "components/common/LanguageBtn";
import Skill from "components/Skil";

interface refType {
  refs: React.RefObject<HTMLElement>;
}

const Header = ({ refs }: refType) => {
  const { i18n } = useTranslation();

  const scrollToSkill = () => {
    refs?.current?.scrollIntoView();
  };

  const changeLanguage = () => {
    i18n.language === "ko-KR"
      ? i18n.changeLanguage("en-US")
      : i18n.changeLanguage("ko-KR");
  };

  return (
    <>
      <div className="header-container">
        {/* !수정필요 */}
        <div>
          <Link to="/">LOGO</Link>
        </div>
        <div onClick={scrollToSkill}>
          <Skill />
        </div>
        <div>
          <Link to="/project">Project</Link>
        </div>
        <div onClick={changeLanguage}>
          <LangBtn />
        </div>
      </div>
    </>
  );
};

export default Header;

 

막상 레이아웃을 잡고 구현하니 변경할 점들이 생겨나서 수정한다면 따로 TIL에 변경 부분을 기록할 예정이다. :)

 


 

헤더 레이아웃(+짧게 등장한 언어 변경 버튼)과 섹션만 나눈 상태로 적용해보았기에 완성도는 없지만 구현한 화면이다.  내용은 없지만, 섹션별로 색을 나눠서 잘 이동하는 것을 확인하도록 만들어보았다.

 

 

'📍 DEV > React & Next.js' 카테고리의 다른 글

useLayoutEffect  (0) 2021.11.24
Random background Image  (0) 2021.10.09
React i18n-next를 이용한 다국어 처리  (0) 2021.09.16