1. 데이터 흐름 (API → 훅 → 컴포넌트)
-
API (
api/items.ts): 백엔드를 부르는 순수 함수 (getItems, createItem, updateItem, deleteItem) -
훅 (
hooks/userItems.ts): 그 API를 React·TanStack Query에 붙여서 데이터/로딩/에러/뮤테이션을 돌려줌. 컴포넌트는 훅만 사용. -
컴포넌트: 페이지를 만드는 조각. App 같은 페이지에서
<ItemList />,<ItemDetail />처럼 사용. 리스트는 배열을 map으로 렌더. -
타입 (
types/item.ts): DTO·엔티티를 TypeScript로 정의 (Item, CreateItemDto, UpdateItemDto). API 요청/응답 모양을 맞춤.
정리: API로 불러온 걸 (필요하면 훅에서 가공해서) 컴포넌트에는 보여줄 것만 넘긴다.
2. 훅과 컴포넌트를 나누는 이유
-
재사용: 같은
useItemsQuery()를 목록 화면·다른 컴포넌트에서 공통 사용 -
역할 분리: 훅 = 데이터/로직, 컴포넌트 = UI
-
테스트: 훅만 따로, 컴포넌트는 “데이터 있다” 가정하고 UI만 테스트하기 쉬움
3. 뮤테이션(Mutation)
-
의미: TanStack Query에서 서버 데이터를 바꾸는 작업 (생성·수정·삭제)
-
Query: 읽기(GET), 자동 실행. Mutation: 쓰기(POST/PATCH/DELETE), 직접 mutate() 호출할 때만 실행
-
예: useCreateItemMutation, useUpdateItemMutation, useDeleteItemMutation
4. invalidateQueries를 쓰는 이유
-
Query는 서버에서 받은 데이터를 캐시에 둠 (queryKey로 구분).
-
Mutation이 성공하면 서버 데이터는 이미 바뀌었는데, 화면은 예전 캐시를 보고 있음.
-
invalidateQueries({ queryKey: [‘items’] }) = “이 캐시는 더 이상 믿지 않아. 다음에 이 쿼리 쓰면 다시 fetch 해.”
-
그래서 생성/수정/삭제 후 목록이 자동으로 갱신됨.
5. 캐시 = “메모리에 저장”의 의미
-
TanStack Query 캐시는 서버(nginx, 인스턴스) 메모리가 아니라 브라우저(클라이언트) 쪽에 있음.
-
localStorage / sessionStorage 아님.
-
캐시: JS 실행 환경의 메모리(RAM). 탭 열려 있는 동안만 유지, 새로고침하면 사라짐.
-
localStorage: 디스크에 저장, 탭/브라우저 닫아도 유지.
-
sessionStorage: 탭 닫으면 삭제.
-
즉, 그 탭이 점유한 사용자 기기의 RAM을 쓰는 것. 캐시가 크면 그 탭의 메모리 사용량이 조금 늘어남.
6. 비동기 (async/await, Promise) 주의점
-
await 빼먹기: Promise 객체만 받고, 실제 값/에러를 못 다룸.
-
에러 처리: async 함수는 실패 시 rejected Promise 반환. await 또는 .catch() 없으면 Unhandled Rejection → Node 15+에서는 프로세스 종료될 수 있음.
-
순차 vs 병렬: 독립된 요청은
Promise.all([fetchA(), fetchB()])로 동시에 보내는 게 유리. -
반복문 + await: N번 순차 실행. 가능하면 bulk insert/update 등으로 쿼리 횟수 줄이기. N+1 문제 = 목록 1번 + 항목마다 1번 쿼리 나가는 패턴.
-
async 함수: 반환값이 자동으로 Promise로 감싸짐. await 없이 받으면 “안쪽 값”에 바로 접근 불가.
8. 백엔드·프론트 DTO 맞추기
-
프론트
CreateItemDto,UpdateItemDto는 백엔드 DTO와 같은 모양으로 두는 게 좋음. -
createItem(dto: CreateItemDto), updateItem(id, dto: UpdateItemDto) 처럼 body에는 DTO 필드만 전송 (전체 Item 아님).
-
수정은 PATCH 사용 (PUT 아님).
9. 폴더 구조 (Zustand, TanStack Query, shadcn 포함 시)
src/
├── api/ # fetch 래퍼
├── store/ # Zustand (전역 상태)
├── hooks/ # useQuery, useMutation 훅 (또는 queries/)
├── components/
│ ├── ui/ # shadcn 컴포넌트
│ └── ... # 우리가 만든 컴포넌트
├── pages/
├── routes/
├── types/
10. 기타
-
React .env:
VITE_로 시작하는 변수만 브라우저에서 사용 가능. 개발 시 프록시 쓰면 필수 아님. -
psql:
\dt= 테이블 목록,\d= describe.\d 테이블명= 해당 테이블 구조. -
Cursor 단축키:
Ctrl+Tab/Ctrl+Shift+Tab탭 이동,Cmd+P(Mac) /Ctrl+P(Win) 파일 열기.