Skip to content

[Enhancement] API 호출 로직을 커스텀 훅으로 분리 (관심사 분리) #20

@seorinn

Description

@seorinn

배경

현재 여러 컴포넌트가 API 호출, 로딩 상태, 에러 처리를 직접 담당하고 있어 관심사가 분리되지 않았습니다. 동일한 API를 여러 컴포넌트에서 각각 호출하는 중복도 있습니다.

현재 문제

// MainHome/EventBox, EventHome, SearchPage 등에서 동일 패턴 반복
const [promotions, setPromotions] = useState([]);
const [isLoading, setIsLoading] = useState(false);

useEffect(() => {
  const fetch = async () => {
    setIsLoading(true);
    try {
      const res = await getPromotionList(params);
      setPromotions(res.items);
    } catch (e) {
      console.log(e); // 에러 처리 없음
    } finally {
      setIsLoading(false);
    }
  };
  fetch();
}, []);

컴포넌트가 렌더링 + 데이터 패칭 + 에러 처리를 모두 담당.

개선 방향

// src/hooks/usePromotionList.ts
function usePromotionList(params: PromotionListParams) {
  const [promotions, setPromotions] = useState<Promotion[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    let cancelled = false;
    setIsLoading(true);
    getPromotionList(params)
      .then((res) => { if (!cancelled) setPromotions(res.items); })
      .catch((e) => { if (!cancelled) setError(e); })
      .finally(() => { if (!cancelled) setIsLoading(false); });
    return () => { cancelled = true; }; // 언마운트 시 취소
  }, [JSON.stringify(params)]);

  return { promotions, isLoading, error };
}

// 사용
function EventBox() {
  const { promotions, isLoading } = usePromotionList({ page: 0, pageSize: 5 });
  if (isLoading) return <Loading />;
  return <>{promotions.map(...)}</>;
}

생성 대상 훅

  • usePromotionList(params)
  • usePhotographerList(params)
  • useUserProfile()

관련 파일

  • src/pages/MainHome/EventBox/index.tsx
  • src/pages/MainHome/PhotographerBox/index.tsx
  • src/pages/EventHome/index.tsx
  • src/pages/PhotographersHome/index.tsx
  • src/pages/SearchPage/index.tsx

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions