[React] 가로 스크롤 구현하기(feat. Typescript, Tailwind)

2024. 11. 10. 23:08· 트러블슈팅
목차
  1. 🐝 전체 코드
  2. 🐝 코드 설명
  3. 🐝 적용하기

개발을 하다 보면 일반적인 세로 방향 스크롤이 아닌 아래의 그림처럼 가로 방향으로 넘어가는 스크롤이 필요한 경우가 있습니다.

가로 방향으로 넘어가는 스크롤

따라서 이번 글에서 가로 스크롤에 필요한 코드를 정리해보겠습니다.

 


🐝 전체 코드

아래의 코드는 'useHorizontalScroll.ts'라는 이름의 커스텀 훅으로, 원하는 요소에 가로 스크롤을 적용합니다.

import { useRef, useEffect, useCallback } from 'react';

export const useHorizontalScroll = () => {
  const listWrapperRef = useRef<HTMLUListElement>(null);

  const handleWheel = useCallback((e: WheelEvent) => {
    const container = listWrapperRef.current;
    
    if (container) {
      const delta = e.deltaY;
      container.scrollLeft += delta;
      e.preventDefault();
    }
  }, []);

  useEffect(() => {
    const container = listWrapperRef.current;
    
    if (container) {
      container.addEventListener('wheel', handleWheel);
      
      return () => {
        container.removeEventListener('wheel', handleWheel);
      };
    }
    
    return () => {};
  }, [handleWheel]);

  return listWrapperRef;
};

코드는 크게 네 부분으로 나눌 수 있으며 아래에서 자세히 살펴보겠습니다.

 


🐝 코드 설명

1) 'listWrapperRef' 생성

const listWrapperRef = useRef<HTMLUListElement>(null);
  • 스크롤이 적용될 요소는 보통 리스트 요소(<ul>)이므로 useRef 훅을 사용하여 'listWrapperRef' 변수를 생성합니다.
  • 해당 ref는 스크롤이 적용될 요소와 연결됩니다.

 

2) 'handleWheel' 함수 정의

const handleWheel = useCallback((e: WheelEvent) => {
  const container = listWrapperRef.current;
    
  if (container) {
    const delta = e.deltaY;
    container.scrollLeft += delta;
    e.preventDefault();
  }
}, []);
  • 'handleWheel' 함수가 받는 event(e)인 WheelEvent는 사용자의 마우스 휠 이벤트 객체입니다.
  • 마우스 휠이 위아래(세로 방향)로 움직인 정도인 deltaY 값을 연결된 요소의 scrollLeft 속성에 더해, 해당 요소가 가로로 스크롤되도록 합니다.
  • e.preventDefault()를 호출하여 기본 세로 스크롤 이벤트를 막습니다.
참고로 'const delta'를 정의할 때 'e.detail' 또는 'e.wheelDelta' 속성이 사용되는 경우가 있습니다.
이는 과거에 사용되던 속성으로 최신 브라우저 표준에서는 지원하지 않습니다. 따라서 'deltaX', 'deltaY', 'deltaZ' 속성을 사용하면 됩니다.

 

3) useEffect로 이벤트 리스너 등록

useEffect(() => {
  const container = listWrapperRef.current;
    
  if (container) {
    container.addEventListener('wheel', handleWheel);
      
    return () => {
      container.removeEventListener('wheel', handleWheel);
    };
  }
    
  return () => {};
}, [handleWheel]);
  • useEffect 훅으로 컴포넌트가 마운트 될 때 'wheel' 이벤트 리스너를 등록하고,
  • 원마운트될 때 해당 이벤트 리스너를 제거하여 메모리 누수를 방지합니다.

 

4) 'listWrapperRef' 반환

return listWrapperRef;
  • 마지막으로 앞서 생성한 'listWrapperRef'를 반환하여 가로 스크롤이 필요한 요소에 ref를 연결할 수 있도록 합니다.

 


🐝 적용하기

원하는 요소에 가로 스크롤을 적용하기 위해 제가 구현한 코드의 일부를 예시로 보겠습니다.

 

폴더 목록이 <ul> 태그로 감싸져 있고, <li> 태그로 감싸진 폴더 항목들이 map()을 통해 화면에 뿌려집니다.

가로 스크롤과 관련되지 않은 코드는 생략하였습니다.

import { useHorizontalScroll } from '@/lib/hooks';

export const FolderList = () => {
  const listWrapperRef = useHorizontalScroll();

  //... 생략
  
  return (
    <div>
      <ul
        className="overflow-x-auto scrollbar-hide"
        ref={listWrapperRef}		// 여기에 연결
      >
        {folderList.map((folder) => (
          <li key={folder.id}>
            <Folder folder={folder} />
          </li>
        ))}
      </ul>
    </div>
  );
};
  • 위에서 만들어준 'useHorizontalScroll.ts' 파일을 임포트해옵니다.
  • useHorizontalScroll() 커스텀 훅에서 반환하는 'listWrapperRef'를 받아옵니다.
  • 가로 스크롤을 적용하고 싶은 요소에 ref 속성을 활용하여 'ref={listWrapperRef}'를 등록해줍니다.

 


읽어주셔서 감사합니다:)

 

  1. 🐝 전체 코드
  2. 🐝 코드 설명
  3. 🐝 적용하기
'트러블슈팅' 카테고리의 다른 글
  • [React] useQuery() 사용 시 값이 업데이트 되지 않는 문제 해결하기
  • [React] 모달(modal) 레이아웃 구현하기(feat. Typescript, Tailwind)
  • [Typescript] 이미지 타입 처리하기(File, string, StaticImageData, null)
  • [Next.js] 상황에 맞는 웹 페이지 렌더링 방식 선택하기
emmaOH!
emmaOH!
emmaOH!
개발자구역
emmaOH!
전체
오늘
어제
  • 분류 전체보기 (67)
    • Frontend (9)
    • React (7)
    • Next.js (2)
    • Typescript (2)
    • Javascript (15)
    • HTML & CSS (13)
    • Git (4)
    • 트러블슈팅 (12)
    • etc. (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

  • 티스토리챌린지
  • Typescript
  • CSS
  • Next.js
  • React
  • git
  • 오블완
  • 자바스크립트
  • javascript
  • 취업까지달린다
  • 리액트
  • 주석
  • 코드잇스프린트
  • 깃
  • html
  • Frontend
  • 프론트엔드
  • 라이브러리
  • 스프린트프론트엔드8기
  • 타입스크립트
hELLO · Designed By 정상우.v4.3.0
emmaOH!
[React] 가로 스크롤 구현하기(feat. Typescript, Tailwind)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.