Redux Thunk를 사용한 무한 스크롤 기능 구현 예제

목차

소개

무한 스크롤은 웹 페이지에서 스크롤을 내릴 때 새로운 데이터를 불러오는 기능입니다. 이 기능은 사용자 경험을 향상시키고 페이지의 성능을 향상시킬 수 있습니다. 이번 예제에서는 Redux Thunk를 사용하여 무한 스크롤 기능을 구현하는 방법을 살펴보겠습니다.

구현 방법

  1. 초기 상태를 설정합니다. 이 예제에서는 scroll이라는 상태 변수와 불러올 데이터를 담을 items 배열을 사용합니다.
  2. 처음 페이지 로딩 시 fetchItems 액션을 디스패치하여 초기 데이터를 가져옵니다.
  3. 스크롤 이벤트를 감지하는 함수를 만들고, 스크롤이 페이지 하단에 도달했을 때 fetchItems 액션을 디스패치하여 추가 데이터를 가져옵니다.
  4. fetchItems 액션에서는 API를 호출하여 새로운 데이터를 가져옵니다. 성공적으로 데이터를 가져온 경우 addItems 액션을 디스패치하여 상태를 업데이트합니다.

예제 코드

// actions.js
import axios from 'axios';

// 무한 스크롤 액션 타입
export const ADD_ITEMS = 'ADD_ITEMS';

// 데이터 가져오는 액션
export const fetchItems = () => {
  return async (dispatch, getState) => {
    const { scroll, items } = getState();

    try {
      const response = await axios.get(`/api/items?scroll=${scroll}`);
      const newItems = response.data;

      dispatch(addItems(newItems));
    } catch (error) {
      console.error('Error fetching items:', error);
    }
  };
};

// 데이터 추가하는 액션
export const addItems = (newItems) => {
  return {
    type: ADD_ITEMS,
    payload: newItems,
  };
};

// reducers.js
import { ADD_ITEMS } from './actions';

const initialState = {
  scroll: 0,
  items: [],
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_ITEMS:
      return {
        ...state,
        scroll: state.scroll + 1,
        items: [...state.items, ...action.payload],
      };
    default:
      return state;
  }
};

export default reducer;

// ScrollComponent.js
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { fetchItems } from './actions';

const ScrollComponent = () => {
  const dispatch = useDispatch();
  const items = useSelector((state) => state.items);

  const handleScroll = () => {
    const { scrollTop, scrollHeight, clientHeight } = document.documentElement;

    if (scrollTop + clientHeight === scrollHeight) {
      dispatch(fetchItems());
    }
  };

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  return (
    <div>
      {items.map((item) => (
        <div key={item.id}>{item.name}</div>
      ))}
    </div>
  );
};

export default ScrollComponent;

참고 자료

#Redux #Thunk