221209 TIL 채팅 입력시 자동으로 scroll 맨 밑으로 이동하게 하기

오늘은 채팅창 css를 적용하다 수정해야 할 부분이 생겨서 다시 채팅창을 리팩터링 하는 작업을 했다.
문제 상황은 채팅 메시지가 채팅창의 세로 사이즈가 넘어갈 시 overflow-y: auto를 줘서 자동으로 세로 스크롤이 생기게 했다.
그런데 채팅을 새로 입력했을때 세로 스크롤만 생기지 스크롤이 자동으로 맨 밑으로 내려가는 게 아니라 사용자가 직접 스크롤을 내려서 최신 메시지를 확인해야 하는 문제가 발생했다.
그래서 채팅을 입력했을때 자동으로 스크롤이 맨 밑으로 내려가게 하는 방법을 찾아 해결했다.

 

useRef

useRef를 사용했는데 useRef를 간단히 말하면 React에서 특정 DOM요소에 접근할 때 사용하는 hook이다.
자바스크립트를 사용할 경우에는 getElementById나 querySelector 같은 함수를 사용했는데 리액트에서는 useRef를 사용해야 한다.

 

useRef의 사용방법은 아래와 같다.

 

1. 원하는 변수명으로 useRef()를 선언한다.

const messages = useRef();

 

2. 선택하고자 하는 DOM에 위에서 선언해준 변수명을 ref 와 함께 속성으로 추가한다.

<div ref={messages}></div>

3. 사용하고 싶은 곳에 변수명.current로 사용하면 된다.

const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
 };

 

 

위의 useRef를 사용해 채팅 scroll을 맨 밑으로 구현한 방법은 아래와 같다.

 

우선 messages라는 변수명으로 useRef를 선언해줬다.

 

messages는 채팅 메시지를 출력하는 li요소에 ref속성을 추가해줬다.

 

이후 scrollToBottom 메서드를 만들어 채팅 메시지가 들어있는 배열이 변할 때마다 (즉 메시지가 배열 안에 추가가 될 때마다) scrollToBottom이라는 메서드를 실행시키게 했다.

scrollToBottom메서드를 실행시키면 실행되는 코드는 messages안에 current 값이 있으면(채팅을 입력하면 current값이 존재, current값이 없을 경우 에러가 발생하지 않도록?.(옵셔널 체이닝) 사용) scrollIntoView메서드를 실행시키게 했는데 scrollIntoView메서드는 messages로 선택한 엘리먼트가 있는 위치로 이동시켜주는 내장 메서드이다.

그래서 채팅을 입력해서 스크롤이 생길 시 채팅 메시지가 추가되는 곳인 맨 밑으로 스크롤이 자동으로 내려가도록 했다.

 

이제 프로젝트 마감까지 주말밖에 남지 않았는데 어드민 페이지 css를 빨리 마무리 하고 사용자 기능 디테일적인 부분을 잡아보자

 

참조 : https://stackoverflow.com/questions/37620694/how-to-scroll-to-bottom-in-react