스크롤이 있는 페이지에서 특정요소로 이동해야하는 경우가 있습니다. 가령 채팅을 구현할 때는 메세지가 추가될 때마다 추가된 요소에 스크롤이 고정되어야하는 경우가 대표적인 예입니다. 저희 프로젝트에서는 글을 작성할 때 사진을 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;
작동 모습
'FE > react' 카테고리의 다른 글
[React] 리액트 렌더링 과정 (1) | 2024.01.14 |
---|---|
[React] 언제 어떻게 state와 useEffect를 사용해야할까? (0) | 2023.10.13 |
[React] 토스트팝업/스낵바(toast popup/snack bar)직접 구현하기 (0) | 2023.05.24 |
[React] react-query useInfiniteQuery로 무한스크롤 구현하기 (2) | 2023.05.22 |
[React] 모바일 웹 100vh 스크롤 버그 + tailwind 적용법 (2) | 2023.05.08 |
댓글