[React - TIL] 채팅 스크롤 맨 아래로 내리는 방법 진짜 최종

Leesu·2023년 7월 5일
1
post-thumbnail

채팅 서비스를 만드는 중, 버튼을 클릭하면 채팅의 맨 아래로 내려가는 기능이 필요해졌다.
채팅이 추가되면 자동으로 스크롤이 아래로 이동하는 기능은 만들어보았어도..
맨 아래로 보내는 기능은 처음이라.. 두근두근..!

🟡 스크롤이 맨 아래에 있는지?

가장 먼저 해야할 것.
스크롤이 맨 아래에 있는지(제일 하단에 있는지) 확인해야한다.

스크롤이 맨 아래에 있는지 감지하려면, scrollTopscrollHeightclientHeight 를 뺀 값이 크거나 작은지 확인하면 된다.

e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight

이러면 스크롤이 맨 아래에 있는지 감지할 수 있다.

function ChatList(props) {
  const [ScrollY, setScrollY] = useState(0); // 스크롤값을 저장하기 위한 상태

  // ... 코드생략
  const handleFollow = (e) => {
      setScrollY(
        // 스크롤이 맨 아래에 있는지 감지
        e.target.scrollTop >= e.target.scrollHeight - e.target.clientHeight
      );
    };
  
return (
	// ... 코드생략
    <Grid
          onScroll={handleFollow}
          sx={{
          // ... 코드생략

handleFollow 함수를 통해 스크롤 위치를 감지하고,
스크롤이 맨 아래에 있는지에 대한 여부를 ScrollY 라는 State 에 저장해주면된다.

참고로 스크롤이 되야하는, 그러니까 채팅 리스트가 띄워지는 채팅 박스(?)에 onScroll 이벤트를 걸어야지 정확하고,
아닐 경우 스크롤이 잘못 감지될 수 있으니 주의해야한다.

🟡 useEffect 로 관리하기

초기화 단계에서 window 객체에 scroll 이벤트 리스너를 추가하고,
컴포넌트가 언마운트될 때 이벤트 리스너를 제거하도록 추가했다.

useEffect(() => {
    const watch = () => {
      window.addEventListener("scroll", handleFollow);
    };
    watch(); // addEventListener 함수 실행
    return () => {
      window.removeEventListener("scroll", handleFollow); // addEventListener 함수 삭제
    };
  });

효율적인 scroll 이벤트 관리를 위해 꼭 useEffect 를 사용해주자!

🟡 맨 아래로 내려가는 버튼

자 이제 클릭했을 때 채팅 맨 아래로 이동시키는 버튼만 추가하면되는데,
나는 이 버튼이 계속 보이는 것이 아니라

  1. 채팅이 있을 때
  2. 스크롤이 생겼을 때
  3. 스크롤이 제일 하단이 아닐 때

위의 3가지 조건에 부합할 때만 버튼이 보이도록 설정해 주었다.

 {/* 맨 아래로 이동시키는 버튼 */}
  {chatList?.length > 0 && ScrollY !== 0 && !ScrollY && (
    <Button
      variant="plan"
      sx={{ position: "absolute", bottom: "10%", right: "1%" }}
      onClick={() =>
        messageEndRef.current.scrollIntoView({ behavior: "smooth" })
      }
    >
      <img src={downbtn} alt={"scroll down btn"} />
    </Button>
  )}

and 연산자를 통해 조건을 추가해주었고,
클릭 시 제일 하단으로 슝 ~ 잘 내려간다 ~ 💨


기능을 직접 만들기 전, react-scroll-to-bottom 이라는 npm 라이브러리를 사용할까 했었는데,
이게.. 내리는 버튼이 그냥 회색 동그라미 버튼이다.. 진짜 걍 이럼 -> ⚫ ㅋㅋ
화살표라도 있음 좋겠는데 싶어서 커스텀을 하려는데..
여간 힘든게 아니더라.......🤔 ㅋ 이걸로 시간 보낼바에야 직접 만들겠다 싶어서 만들었다.

npm 으로 설치만하고 높이만 지정해주면 위에서 만든 기능을 바로 사용할 수 있는데,
버튼이 못생겨서 그냥 피그마에서 직접 아이콘 만들어서 넣고 스크롤 기능 만들어버렸다.
그래도 만들어서 뿌듯 :)

혹시나 버튼이 뭐 어떻게 생겨도 상관이 없다면.. 여기 참고!!!

profile
기억력 안 좋은 FE 개발자의 메모장

0개의 댓글