[Week13] React(TypeScript) 기반의 동적 UI 개발(8)

Younha Lee·3일 전

TIL

목록 보기
60/62

지난 시간에 이어 프로젝트 중간 회고를 진행하고, 부족했던 기능들을 추가로 구현해 볼게요.

프로젝트 중간 회고

회고를 하는 궁극적인 이유는 프로젝트를 더 잘 수행하기 위함이에요. 성장을 도모하고 문제를 해결하며, 유연성과 퍼포먼스를 향상시키는 데 목적이 있어요.

지금까지 진행한 학습 주제는 타입과 데이터 모델 정의, 컴포넌트 작성, CSS 스타일링, 커스텀 훅 활용 등이에요. 여기에 생산성을 높이기 위해 스니펫을 사용하고, 데이터 모델 정의부터 리팩토링까지 이어지는 기능 단위의 작업 흐름을 정립하는 과정도 고민해 보았어요. 일정한 틀을 두고 작업하면 다음 단계에 대한 고민을 줄이고 휴먼 에러를 방지할 수 있어요.

이번 프로젝트의 Keep(유지할 점), Problem(문제점), Try(시도할 점)를 정리해 보았어요.

  • Keep: 회원가입부터 주문까지의 흐름 경험, 생산성을 고려한 개발, 데이터 흐름에 맞춘 설계
  • Problem: 테마 스위처 미적용, 상대 경로 사용으로 인한 import 복잡도, 중복 코드, CSS 스타일링 미정리
  • Try: 테마 스위처 재배치, 절대 경로 적용, 중복 코드 제거, useAuth 훅 도입

절대 경로 설정 (CRACO)

프로젝트 규모가 커지면 상대 경로를 사용할 때 경로 지정이 매우 복잡해져요. 이를 해결하기 위해 절대 경로를 설정하는 것을 권장해요. CRA 환경에서는 CRACO 라이브러리를 활용해 설정을 덮어쓸 수 있어요.

@craco/cracocraco-alias 를 설치한 뒤, 프로젝트 루트에 craco.config.js 파일을 생성하여 설정을 추가해요. 이후 package.json 의 스크립트를 변경하여 적용해요.

"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test"
}

VSCode 커스텀 스니펫 만들기

VSCode에서 별도의 확장 프로그램을 설치하지 않고도 커스텀 스니펫을 만들어 사용할 수 있어요. 자주 사용하는 코드 블록을 스니펫으로 등록해 두면 반복적인 타이핑을 줄여 생산성을 높일 수 있어요.

useAuth 커스텀 훅 적용

이전 구현에서는 로그인 관련 로직을 컴포넌트 내부에 직접 작성했어요. 이를 분리하여 useAuth 라는 커스텀 훅을 만들면 상태 관리가 훨씬 수월해져요. 회원가입, 로그인, 비밀번호 초기화 요청 등의 로직을 모아두고 필요한 컴포넌트에서 가져다 사용하도록 리팩토링을 진행했어요.

const useAuth = () => {
  const login = async (data) => { 
    // 로그인 로직
  };
  const signup = async (data) => { 
    // 회원가입 로직
  };
  const resetPassword = async (data) => { 
    // 비밀번호 초기화 로직
  };

  return { login, signup, resetPassword };
};

TanStack Query (React Query) 도입

과거 React Query로 불렸던 TanStack Query를 프로젝트에 도입했어요. 이 라이브러리는 서버 상태를 가져오고, 캐싱하고, 동기화하며, 업데이트하는 비동기 작업을 쉽게 처리하도록 도와줘요.

라이브러리에서 제공하는 useQuery 훅을 사용하면 데이터 패칭뿐만 아니라 로딩 상태도 직관적으로 알 수 있어요. 이를 활용해 데이터를 불러오는 동안 사용자에게 보여줄 로딩 화면을 쉽게 구현할 수 있어요.

import { useQuery } from "@tanstack/react-query";

const fetchBooks = async () => {
  const response = await axiosInstance.get("/books");
  return response.data;
};

const BookList = () => {
  const { data, isLoading } = useQuery(["books"], fetchBooks);

  if (isLoading) {
    return <div>로딩 중입니다.</div>;
  }

  return (
    <ul>
      {data.map((book) => (
        <li key={book.id}>{book.title}</li>
      ))}
    </ul>
  );
};
profile
할 땐 하고 놀 땐 노는 일일놀놀입니다.

0개의 댓글