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) 파일 열기.