웹개발

[React] IntersectionObserver DOM의 업데이트(예: 좋아요 버튼 클릭) 이후에야 비로소 IntersectionObserver가 다시 작동할때

Heeyeon Choi 2024. 8. 28. 15:11
728x90

1. IntersectionObserver의 관찰 조건 및 실행 시점 문제

  • 댓글 목록의 렌더링이 완료되지 않았거나, DOM의 변화를 감지하기 전까지 IntersectionObserver가 정상 작동하지 않을 수 있습니다. 이 경우, 새로운 데이터를 불러올 때 IntersectionObserver가 즉시 반응하지 않는 문제가 발생할 수 있습니다.

2. 해결책

방법 1: useLayoutEffect로 렌더링 이후 바로 IntersectionObserver 실행

useEffect 대신 useLayoutEffect를 사용하면, DOM 업데이트 후 바로 IntersectionObserver를 실행할 수 있습니다.

import { useLayoutEffect } from 'react';

useLayoutEffect(() => {
  if (comments.length === 0) return;

  const observer = new IntersectionObserver(
    (entries) => {
      if (entries[0].isIntersecting && comments.length > 0 && !isLoading && currentPage < totalPages) {
        setCursor(comments[comments.length - 1].comment_id);
      }
    },
    { threshold: 0.5 }
  );

  if (lastCommentRef.current) {
    observer.observe(lastCommentRef.current);
  }

  return () => {
    if (lastCommentRef.current) {
      observer.unobserve(lastCommentRef.current);
    }
  };
}, [comments, isLoading, currentPage, totalPages]);

 

방법 2: MutationObserver 추가 사용

  • DOM 변경을 감지하는 MutationObserver를 사용하여, DOM 업데이트 시 IntersectionObserver를 재실행하는 방법입니다. 예를 들어, 좋아요 버튼을 클릭했을 때 DOM이 변경되면 IntersectionObserver가 다시 작동하도록 할 수 있습니다.
useEffect(() => {
  if (comments.length === 0) return;

  const observer = new IntersectionObserver(
    (entries) => {
      if (entries[0].isIntersecting && comments.length > 0 && !isLoading && currentPage < totalPages) {
        setCursor(comments[comments.length - 1].comment_id);
      }
    },
    { threshold: 0.5 }
  );

  const mutationObserver = new MutationObserver(() => {
    if (lastCommentRef.current) {
      observer.observe(lastCommentRef.current);
    }
  });

  if (lastCommentRef.current) {
    observer.observe(lastCommentRef.current);
  }

  mutationObserver.observe(document.body, {
    childList: true,
    subtree: true,
  });

  return () => {
    if (lastCommentRef.current) {
      observer.unobserve(lastCommentRef.current);
    }
    mutationObserver.disconnect();
  };
}, [comments, isLoading, currentPage, totalPages]);

3. 주요 고려 사항

  • 이 문제는 주로 DOM 업데이트 시 IntersectionObserver가 다시 실행되지 않아서 발생하는 것이므로, DOM의 변화를 잘 감지하고 다시 관찰을 시작할 수 있도록 하는 것이 중요합니다.
  • IntersectionObserver는 스크롤이 아닌 요소의 가시성을 기준으로 작동하므로, 요소가 화면에 어떻게 표시되는지(예: 다른 UI 요소에 의해 가려지거나 하는 경우)도 주의가 필요합니다.

이와 같이 useLayoutEffect나 MutationObserver를 추가하여 문제를 해결할 수 있습니다.

728x90