[React][Instagram] 리팩토링 - 무한 스크롤 별도 컴포넌트 생성

GY·2021년 12월 23일
0

리액트

목록 보기
32/54
post-thumbnail
post-custom-banner

Feeds.js

인스타그램 피드들을 감싼 Feeds 컴포넌트 최하단에 intersectionObserver를 관리하는 LoadMoreFeed 컴포넌트를 만들어주었다.

import React, { useEffect, useRef, useState } from 'react';
import Feed from '../Feed/Feed';
import './Feeds.scss';
import Skeleton from '../Skeleton/Skeleton';
import LoadMoreFeed from '../LoadMoreFeed/LoadMoreFeed';

function Feeds() {
  const [page, setPage] = useState(0);
  const [feedList, setFeedList] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  return (
    <div className="feeds-gayun">
      <div className="feed-container">
        {page === 0 && isLoading
          ? createSkeletonFeed(SKELETON_FEED_COUNT)
          : feedList.map((feed, idx) => <Feed key={idx} feed={feed} />)}
      </div>
      <LoadMoreFeed isLoading={page !== 0 && isLoading} setPage={setPage} />
    </div>
  );
}

export default Feeds;

LoadMoreFeed.js

LoadMoreFeed에서는 최초 렌더링 시에 observer를 생성하고, 관찰을 시작한다.

import React, { useRef } from 'react';
import { useEffect } from 'react/cjs/react.development';
import './LoadMoreFeed.scss';

function LoadMoreFeed({ isLoading, setPage }) {
  const feedEndRef = useRef();

  useEffect(() => {
    const observer = new IntersectionObserver(entry => {
      if (entry[0].isIntersecting && entry[0].intersectionRatio > 0.1) {
        setPage(page => page + 1);
      }
    });
    observer.observe(feedEndRef.current);
    return () => {
      observer.unobserve(feedEndRef.current);
    };
  }, []);

  return (
    <div className="feed-end" ref={feedEndRef}>
      {isLoading ? <div className="loading" /> : ''}
    </div>
  );
}

export default LoadMoreFeed;

아직 고민이 필요한 부분

  • 선언한 observer를 클린업 함수에 어떻게 적용해 이펙트를 정리할지
  • feedList가 업데이트 될때마다 observe와 unobserve를 해주도록 의존성 배열을 추가해야 할지
  • feedList가 업데이트 되면서 기존의 피드도 리렌더링되는지의 여부와 막기위해 React.memo를 사용해야 하는지
profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.
post-custom-banner

0개의 댓글