본문 바로가기

공부/Next

[리팩토링] 데이터 로직 분리 및 서버 상태 관리 최적화

반응형

프로젝트를 진행하면서 리팩토링 한 내용에 대해 소개해보려고 합니다.

 

기존 코드 📖

useEffect를 사용한 데이터 요청 처리

`useEffect` 내부에서 `fetchUser` 메서드를 통해 사용자 ID를 가져오고 ID가 있는 경우 서버에 스탬프 데이터를 가져오도록 로직을 짰습니다.

import { useEffect, useState } from 'react';
import { useQuery } from '@tanstack/react-query';

// 로그인 유저 ID 상태
const [userId, setUserId] = useState<string | null>(null);

useEffect(() => {
  const checkUser = async () => {
    const user = await fetchUser();
    if (!user) return;
    setUserId(user);
  };
  checkUser();
}, []);

// 스탬프 데이터 쿼리
const { data: stampList, isLoading, error } = useQuery({
  queryKey: ['stamp'],
  queryFn: async () => {
    if (userId) {
      return await fetchStampActive(userId);
    } else {
      return [];
    }
  },
  enabled: !!userId // userId가 있을 때만 쿼리 실행
});

 

여기서 문제점

 

컴포넌트가 데이터를 직접 요청하고 로직과 UI가 뒤섞여 있어 재사용성가독성이 떨어지는 문제가 있었습니다.

 

리팩토링 코드 📖

사용자 ID 가져오기

사용자 ID를 가져오는 로직을 `useUser`로 분리했습니다. 이를 통해 다른 컴포넌트에서도 쉽게 재사용할 수 있게 되었고, 컴포넌트는 요청 로직과 분리 돼 UI 구현에만 집중할 수 있게 됐습니다.

// useUser.ts

import { useEffect, useState } from 'react';
import browserClient from '@/utils/supabase/client';

const useUser = () => {
  const [userId, setUserId] = useState<string>('');

  useEffect(() => {
    const fetchUser = async () => {
      const { data, error } = await browserClient.auth.getUser();
      if (error || !data?.user) {
        console.log('error');
        return;
      }
      setUserId(data.user.id);
    };
    fetchUser();
  }, []);

  return userId;
};

export default useUser;

 

스탬프 데이터 가져오기

`useStamp`훅에서 `useUser`에서 받아온 ID를 활용해 TanStack Query로 서버에서 데이터를 가져옵니다.

import useUser from './useUser';
import useQuerys from '@/queries/useQuerys';

const useStamp = () => {
  const userId = useUser();

  const { data: stampList, isPending } = useQuerys.useGetStampActive(userId);

  return {
    stampList,
    isPending
  };
};

export default useStamp;

 

서버 요청 관리

서버와의 통신을 위한 코드를 모듈화 해서 쿼리를 캐싱하고 관리했습니다.

import { fetchStampActive } from '@/serverActions/fetchStampActions';
import { useQuery } from '@tanstack/react-query';
import { QUERY_KEY } from './query.keys';

const useGetStampActive = (userId: string) => {
  return useQuery({
    queryKey: QUERY_KEY.STAMPLIST(userId),
    queryFn: () => fetchStampActive(userId),
    enabled: !!userId,
    refetchOnWindowFocus: true
  });
};

const useQuerys = {
  useGetStampActive
};

export default useQuerys;

 

개선 사항 ✨

UI와 비즈니스 로직 분리

UI와 비즈니스 로직을 분리해 독립적으로 동작할 수 있습니다.

 

재사용성 향상

`useUser`,`useStamp`훅을 만들어 재사용 가능하게 했습니다.

 

가독성 및 유지보수 개선

코드 가독성이 높아지고 유지 보수가 수월해졌습니다.

 

 

 

 

아직 많이 부족하기 때문에 조언은 언제나 환영입니다~!!

반응형