Skip to content

프로젝트 초기 세팅

Zustand

Zustand는 클라이언트(UI) 상태를 관리하기 위해 사용한다.

설치

bash
npm i zustand

Zustand를 선택한 이유

  • 가볍고 간단함: 설정이 거의 없고 바로 store를 만들 수 있다.
  • 보일러플레이트가 적음: action/reducer 같은 구조를 강제하지 않는다.
  • React Hook처럼 사용 가능: 필요한 상태만 선택해 구독할 수 있다.
  • 불필요한 리렌더링을 줄이기 쉬움: selector 기반으로 필요한 값만 가져온다.
보일러플레이트(Boilerplate)란?

보일러플레이트는 기능 자체보다 “구조를 맞추기 위해 반복 작성하는 코드”를 말한다. Redux 전통 방식에서는 아래를 반복 작성하는 경우가 많았다.

  • action type
  • action creator
  • reducer
  • store 설정
  • Provider 감싸기

Zustand는 store를 만들고 바로 훅처럼 사용할 수 있어서, 같은 기능을 더 적은 코드로 구현할 수 있다.

ts
import { create } from 'zustand';

type UiState = {
  isOpen: boolean;
  open: () => void;
  close: () => void;
};

export const useUiStore = create<UiState>((set) => ({
  isOpen: false,
  open: () => set({ isOpen: true }),
  close: () => set({ isOpen: false }),
}));

ts
const isOpen = useUiStore((state) => state.isOpen);

Shadcn/ui

shadcn/ui는 “라이브러리처럼 가져다 쓰는 컴포넌트”라기보다는, 프로젝트 내부에 컴포넌트 코드를 생성해서 직접 관리하는 방식이다. Tailwind 기반이고 커스터마이징이 쉬워서 디자인 시스템을 만들기 좋다.

설치

bash
# shadcn/ui 초기 설정
npx shadcn@latest init

@types/node

bash
# Vite 설정 파일에서 Node.js 전역 타입(path, __dirname 등)을 사용하기 위해 설치
npm install -D @types/node

Vite 설정 파일(vite.config.ts)에서 path, __dirname 같은 Node API를 쓰게 되는데, TypeScript가 Node 타입을 모르기 때문에 타입 패키지를 추가해준다.

  • 특히 path alias(@/) 설정할 때 path.resolve(...)를 쓰는 경우가 많아서 같이 설정한다고 한다.

shadcn/ui를 선택한 이유

  • Tailwind 기반이라 스타일 시스템이 한 번 잡히면 속도가 빠름
  • 컴포넌트를 “코드로 소유” → 수정/확장/디자인 변경이 자유로움
  • 디자인 일관성 유지

TanStack Query

TanStack Query는 서버 상태를 다루는 데 최적화된 라이브러리다.
API 응답 데이터는 UI 상태가 아니라 서버에서 온 상태이기 때문에 캐싱, 동기화, 재요청 전략을 명확하게 관리하는 것이 중요하다.

설치

bash
# 서버 상태 관리 라이브러리
npm i @tanstack/react-query

Devtools (개발 중 캐시 확인)

bash
# React Query 상태를 시각적으로 확인하기 위한 개발용 도구
npm install -D @tanstack/react-query-devtools

ESLint 플러그인

bash
# TanStack Query 사용 시 실수를 방지하기 위한 ESLint 플러그인
npm i -D @tanstack/eslint-plugin-query

TanStack Query를 선택한 이유

  • 캐싱이 기본값으로 제공되어 불필요한 요청을 줄일 수 있음
  • 로딩/에러 상태를 패턴으로 깔끔하게 처리 가능
  • refetch 정책, staleTime 등 데이터 신선도 전략을 코드로 관리 가능
  • 서버 상태와 UI 상태 분리로 구조가 명확해짐

기본 옵션

프로젝트 성격에 따라 다르지만, 초기 세팅에서는 다음 옵션을 기본값으로 적용했다.

ts
{
  retry: 1,
  refetchOnWindowFocus: false,
}

옵션 의미

  • retry: 1
    네트워크 오류 등 실패 시 1회만 재시도한다. → 반복 요청으로 인한 불필요한 트래픽과 UX 혼란을 줄이기 위함이다.

  • refetchOnWindowFocus: false 브라우저 탭 전환 시 자동으로 데이터를 다시 불러오는 기본 동작을 비활성화했다. → 의도치 않은 데이터 갱신과 불필요한 요청을 방지하기 위함이다.

이후 서비스 특성에 맞게 staleTime, gcTime, refetchOnReconnect 등을 추가 조정할 수 있다.

ESLint 규칙 적용 포인트 (Query 관련)

TanStack Query는 의존성 배열이나 queryKey 관리에서 실수가 잦아서, ESLint 규칙으로 초기에 막아두는 게 편하다. 또한 queryKey 일관성이 캐싱 품질을 좌우해서 초기에 규칙으로 잡아두는 게 도움이 된다고 한다.

js
  // TanStack Query
  '@tanstack/query/exhaustive-deps': 'error',
  '@tanstack/query/no-unstable-deps': 'error',