혼자 적어보는 노트

[React] 클릭 시 원하는 컴포넌트로 스크롤 이동 본문

React

[React] 클릭 시 원하는 컴포넌트로 스크롤 이동

jinist 2022. 8. 20. 23:09

 

 

 

상세 페이지의 Sidebar에 댓글 아이콘을 누를 경우

상세페이지 하단의 댓글 컴포넌트로 화면을 이동시키는 리모콘 기능을 구현하기로 했다.

 

 

useMoveScroll hook 작성

function useMoveScroll(element: HTMLElement | null) {
  const onMoveToElement = () => {
    element?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };
  return { onMoveToElement };
}

 

element.scrollIntoView

 

이번에 처음 알게된 API인데

해당 element로 스크롤을 이동시켜준다.

 

behavior으로 애니메이션을 정의할 수 있고 block, inline 옵션으로 수직/수평 정렬을 정의할 수 있다.

element.scrollIntoView(true);로 설정 시 바로 지정한 element의 상단으로 이동시킬 수 있다.

 

 

const Sidebar = () => {
	// 코드 생략
    
    const { onMoveToElement } = useMoveScroll(document.getElementById('comment'));


    return(
        <SideButton onClick={onMoveToElement}>
          <Icon name="commentRound" size={32} />
        </SideButton>
    )
}

comment 컴포넌트의 id에 'comment'을 적어주고

해당 element를 직접 지정하여 useMoveScroll에 넣어주었다.

useMoveScroll을 comment컴포넌트와 sideber컴포넌트의 부모 컴포넌트에 위치시킨다면

useRef로도 제어가 가능하다.

 

 

++

❗ 문제상황

Sidebar 컴포넌트가 렌더링 될 때는 Comment 컴포넌트가 렌더링이 되지 않아서

document.getElementById('comment')이 null인 상태이기 때문에

Sidbar가 리렌더가 되야만 click이벤트가 제대로 적용이 되는 문제가 생겼다.

 

 

✅ 문제 해결

클릭을 할 때 element를 찾을 수 있도록 매개변수를 id로 받아서 처리했다.

 

import { useCallback } from 'react';

function useMoveScroll(id: string) {
  const onMoveToElement = useCallback(() => {
    if (typeof window !== 'undefined') {
      const element = document.getElementById(id);
      element?.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  }, [id]);

  return { onMoveToElement };
}

export default useMoveScroll;

 

 

Comments