기능 Cheat sheet

코몽·2024년 9월 12일
1

Cheat Sheet

목록 보기
6/6

무한 스크롤 (intersection observer)

import React, { useCallback, useEffect, useRef, useState } from 'react';

// 임시 데이터 fetch 함수
const mockFetch = (page: number) => {
  return new Promise<string[]>((resolve) => {
    setTimeout(() => {
      resolve(
        Array.from({ length: 10 }, (_, i) => `Item ${(page - 1) * 10 + i + 1}`)
      );
    }, 1000);
  });
};

const InfiniteScroll: React.FC = () => {
  const [items, setItems] = useState<string[]>([]);
  const [page, setPage] = useState(1);
  const [isLoading, setIsLoading] = useState(false);
  const [hasMore, setHasMore] = useState(true);
  const observerRef = useRef<IntersectionObserver | null>(null);
  const loaderRef = useRef<HTMLDivElement | null>(null);

  // 데이터 로드 함수
  const loadMoreItems = useCallback(async () => {
    if (isLoading) return;

    setIsLoading(true);
    const newItems = await mockFetch(page);

    setItems((prevItems) => [...prevItems, ...newItems]);
    setIsLoading(false);

    // 더 이상 데이터가 없다고 가정
    if (newItems.length === 0) {
      setHasMore(false);
    } else {
      setPage((prevPage) => prevPage + 1);
    }
  }, [isLoading, page]);

  // Intersection Observer 설정
  useEffect(() => {
    if (!loaderRef.current || !hasMore) return;

    observerRef.current = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) {
        loadMoreItems();
      }
    });

    observerRef.current.observe(loaderRef.current);

    return () => {
      if (observerRef.current) {
        observerRef.current.disconnect();
      }
    };
  }, [loadMoreItems, hasMore]);

  return (
    <div style={{ height: '100px' }}>
      <h1>Infinite Scroll Example</h1>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
      {isLoading && <p>Loading...</p>}
      {!hasMore && <p>No more items to load</p>}
      <div
        ref={loaderRef}
        style={{ height: '20px', backgroundColor: 'transparent' }}
      />
    </div>
  );
};

export default InfiniteScroll;

debounce (useRef)

import { useRef } from 'react';

const useDebounce = (callback: (...args: any) => void, delay: number) => {
  const timeoutRef = useRef<number | null>(null);

  return (...args: unknown[]) => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
    }

    timeoutRef.current = window.setTimeout(() => {
      callback(...args);
    }, delay);
  };
}

export default useDebounce;

throttle (useRef)

import { useRef } from 'react';

const useThrottle = (callback: (...args: any) => void, delay: number) => {
  const throttleRef = useRef(false);

  return (...args: unknown[]) => {
    if (throttleRef.current) return;

    throttleRef.current = true;
    setTimeout(() => {
      callback(...args);
      throttleRef.current = false;
    }, delay);
  };;
}

export default useThrottle;
profile
프론트엔드 웹 개발자(React) https://code-d-monkey.tistory.com/

0개의 댓글