FE/react

[React] 스크롤 특정 요소로 이동하기

s0ojin 2023. 6. 1. 18:52

 

사진을 추가하면 스크롤에 밀려 사진 추가 버튼이 보이지 않는 모습

 

스크롤이 있는 페이지에서 특정요소로 이동해야하는 경우가 있습니다. 가령 채팅을 구현할 때는 메세지가 추가될 때마다 추가된 요소에 스크롤이 고정되어야하는 경우가 대표적인 예입니다. 저희 프로젝트에서는 글을 작성할 때 사진을 10개까지 추가할 수 있는데, 사진을 추가할 때마다 스크롤이 맨 뒤에 위치해서 사진 추가버튼이 항상 유저에게 보이도록 하고 싶었습니다.

 

구현 방법


element.scrollIntoView를 활용하면 원하는 element로 스크롤을 이동시킬 수 있습니다.

 

MDN에서 소개하고 있는 JS에서의 활용 방법입니다. 포커싱하고 싶은 요소를 getElementById로 불러옵니다. behavior같은 옵션을 통해 스크롤을 부드럽게 내리기 등의 설정을 추가할 수 있습니다. 자세한 내용은 MDN을 참고해주세요.

const element = document.getElementById("box");

element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({ block: "end" });
element.scrollIntoView({ behavior: "smooth", block: "end", inline: "nearest" });

 

 

만약 저처럼 리액트에서 구현하고 싶으시다면 useRef를 통해 요소를 가져오고 useEffect를 활용해 특정 요소가 변경될 때마다 작동하도록 하시면 됩니다. 

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

function BoardCreate() {

  // 스크롤에서 포커스하고 싶은 요소에 적용할 ref
  // 저의 경우 사진추가 버튼입니다. 
  const imageEndRef = useRef<HTMLDivElement | null>(null);
  
  // 첫 렌더링 때와 imagePreview가 변경될 때마다(사진이 추가되거나 삭제될 때마다) 특정요소(사진추가버튼)로 이동
  useEffect(() => {
    imageEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [imagePreview]);
  
  return (
    <div className="container">
      <form onSubmit={handleSubmit(onSubmit)} className="w-full px-[2rem]">
        {/* 기타 관련없는 코드 중략 */}
        <div>
          <label htmlFor="picture">
            <input
              id="picture"
              type="file"
              className="hidden"
              accept="image/*"
              onChange={handleAddImages}
            />
            {/* 사진 추가버튼에 ref추가 */}
            <div
              ref={imageEndRef}
              className="flex h-[7rem] w-[7rem] items-center justify-center rounded-[1rem] bg-black-10">
              <PlusIcon className=" fill-white" />
            </div>
          </label>
        </div>
      </form>
    </div>
  );
}

export default BoardCreate;

 

작동 모습


이미지를 추가하면 스크롤이 사진추가버튼이 있는 맨뒤로 이동