Skip to content

Conversation

@hyeok02
Copy link
Contributor

@hyeok02 hyeok02 commented Dec 21, 2025

πŸ“ λ―Έμ…˜ 번호

10μ£Όμ°¨ Misson 1.2, ν”„λž™ν‹°μŠ€ 1,2

πŸ“‹ κ΅¬ν˜„ 사항

  • λžœλ”λ§ μ΅œμ ν™”
  • vercel 배포

πŸ“Ž μŠ€ν¬λ¦°μƒ·

2025-12-21.210629.1.mp4

βœ… 체크리슀트

  • Merge ν•˜λ €λŠ” λΈŒλžœμΉ˜κ°€ μ˜¬λ°”λ₯΄κ²Œ μ„€μ •λ˜μ–΄ μžˆλ‚˜μš”?
  • λ‘œμ»¬μ—μ„œ μ‹€ν–‰ν–ˆμ„ λ•Œ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šλ‚˜μš”?
  • λΆˆν•„μš”ν•œ 주석이 μ œκ±°λ˜μ—ˆλ‚˜μš”?
  • μ½”λ“œ μŠ€νƒ€μΌμ΄ μΌκ΄€μ μΈκ°€μš”?

πŸ€” 질문 사항

@hyeok02 hyeok02 requested a review from woojo230 December 21, 2025 12:13
@hyeok02 hyeok02 self-assigned this Dec 21, 2025
@github-actions
Copy link

πŸ€– Gemini μ½”λ“œλ¦¬λ·° κ²°κ³Ό

μ•ˆλ…•ν•˜μ„Έμš”. μ‹œλ‹ˆμ–΄ ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμžλ‘œμ„œ μ œκ³΅ν•΄μ£Όμ‹  Pull Request의 λͺ¨λ“  파트(1/7 ~ 7/7)λ₯Ό λ©΄λ°€νžˆ κ²€ν† ν–ˆμŠ΅λ‹ˆλ‹€.

μ „λ°˜μ μœΌλ‘œ λͺ¨λ˜ ν”„λ‘ νŠΈμ—”λ“œ 기술 μŠ€νƒ(React Query, React Hook Form, Zod, Tailwind CSS)을 효과적으둜 μ μš©ν•˜κ³  κ³„μ‹œλ©°, useCallback, useMemo, memo와 같은 React μ΅œμ ν™” 훅에 λŒ€ν•œ 이해와 적용 λ…Έλ ₯이 λ‹λ³΄μž…λ‹ˆλ‹€. 특히, 계산 λΉ„μš©μ΄ 큰 λ‘œμ§μ— useMemoλ₯Ό μ‚¬μš©ν•˜κ±°λ‚˜, loading="lazy" 속성을 톡해 μ„±λŠ₯을 κ°œμ„ ν•˜λ €λŠ” μ‹œλ„λŠ” 맀우 κΈμ •μ μž…λ‹ˆλ‹€.

μ•„λž˜λŠ” λͺ¨λ“  파트의 리뷰 λ‚΄μš©μ„ ν†΅ν•©ν•˜μ—¬ ν”„λ‘œμ νŠΈ μ „λ°˜μ˜ μ„€μ •, μ˜μ‘΄μ„±, API 계측, μ»€μŠ€ν…€ ν›…, μ»΄ν¬λ„ŒνŠΈ, μœ ν‹Έλ¦¬ν‹° νŒŒμΌμ— 걸쳐 μ„±λŠ₯, νƒ€μž… μ•ˆμ •μ„±, μ½”λ“œ ν’ˆμ§ˆ, μœ μ§€λ³΄μˆ˜μ„± μΈ‘λ©΄μ—μ„œ κ°œμ„ ν•  수 μžˆλŠ” ꡬ체적인 μ œμ•ˆλ“€μ„ μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.


리뷰 μš”μ•½ 및 핡심 κΆŒκ³ μ‚¬ν•­

이번 PRμ—μ„œ κ°€μž₯ μ€‘μš”ν•˜κ²Œ κ°œμ„ μ„ κΆŒκ³ ν•˜λŠ” 사항듀은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  1. React 19 및 babel-plugin-react-compiler μ‚¬μš© μž¬κ²€ν† : 아직 μ•ˆμ •ν™”λ˜μ§€ μ•Šμ€ κΈ°μˆ μ΄λ―€λ‘œ ν”„λ‘œλ•μ…˜ 적용 μ‹œ μ‹ μ€‘ν•œ μ ‘κ·Όκ³Ό μΆ©λΆ„ν•œ ν…ŒμŠ€νŠΈκ°€ ν•„μš”ν•©λ‹ˆλ‹€.
  2. ESLint νƒ€μž… 기반 κ·œμΉ™ 및 Flat Config λ§ˆμ΄κ·Έλ ˆμ΄μ…˜: ESLint 9.x에 맞좰 Flat Config둜 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•˜κ³ , @typescript-eslint/recommended-type-checked ν”ŒλŸ¬κ·ΈμΈμ„ ν™œμ„±ν™”ν•˜μ—¬ νƒ€μž…μŠ€ν¬λ¦½νŠΈ μ½”λ“œμ˜ μ•ˆμ •μ„±μ„ κ·ΉλŒ€ν™”ν•˜μ„Έμš”.
  3. react-queryλ₯Ό @tanstack/react-query μ΅œμ‹  λ²„μ „μœΌλ‘œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜: 더 이상 μœ μ§€λ³΄μˆ˜λ˜μ§€ μ•ŠλŠ” react-query v3 λŒ€μ‹  μ΅œμ‹  버전을 μ‚¬μš©ν•˜μ—¬ μ„±λŠ₯, λ²ˆλ“€ 크기, νƒ€μž… 지원을 κ°œμ„ ν•˜μ„Έμš”.
  4. axios.ts의 ν™˜κ²½ λ³€μˆ˜ 및 토큰 관리 κ°œμ„ : baseURL 및 토큰 이름을 ν™˜κ²½ λ³€μˆ˜μ™€ μƒμˆ˜λ‘œ λΆ„λ¦¬ν•˜κ³ , 인증 μ‹€νŒ¨ 처리 λ‘œμ§μ„ 쀑앙 μ§‘μ€‘ν™”ν•˜μ—¬ μœ μ§€λ³΄μˆ˜μ„±μ„ λ†’μ΄μ„Έμš”.
  5. μ»€μŠ€ν…€ ν›… 및 μ»΄ν¬λ„ŒνŠΈμ˜ useCallback 및 memo 적용 νŒ¨ν„΄ κ°œμ„ : CountButton, TextInput, handleIncreaseCount λ“±μ—μ„œ useCallback의 μ˜μ‘΄μ„± λ°°μ—΄ 및 memo의 효과λ₯Ό μ €ν•΄ν•˜λŠ” 인라인 ν•¨μˆ˜ μ‚¬μš© νŒ¨ν„΄μ„ μ΅œμ ν™”ν•˜μ„Έμš”.
  6. TMDB API μš”μ²­ νš¨μœ¨ν™” 및 λŒ€κ·œλͺ¨ 리슀트 λ Œλ”λ§ μ΅œμ ν™”: useMovieSearchμ—μ„œ include_adult νŒŒλΌλ―Έν„°λ₯Ό μ„œλ²„ μš”μ²­μ— ν¬ν•¨ν•˜κ³ , UseMemoPage와 같이 λŒ€κ·œλͺ¨ 데이터λ₯Ό λ Œλ”λ§ν•  λ•Œ 가상화(Virtualization) λ˜λŠ” νŽ˜μ΄μ§€λ„€μ΄μ…˜μ„ κ³ λ €ν•˜μ„Έμš”.

톡합 μ½”λ“œ 리뷰 상세 λ‚΄μš©

1. ν”„λ‘œμ νŠΈ μ „λ°˜: μ„€μ • 및 μ˜μ‘΄μ„± 관리

  • React 19 버전 채택 μ „λž΅ 및 babel-plugin-react-compiler μ‚¬μš© μž¬κ²€ν† 
    • 문제점: react 및 react-dom이 ^19.2.0 (RC 버전)으둜 μ„€μ •λ˜μ–΄ 있고, babel-plugin-react-compiler와 같은 μ‹€ν—˜μ μΈ ν”ŒλŸ¬κ·ΈμΈμ„ μ‚¬μš© μ€‘μž…λ‹ˆλ‹€. μ•ˆμ •ν™”λ˜μ§€ μ•Šμ€ 버전은 μ˜ˆμƒμΉ˜ λͺ»ν•œ 버그λ₯Ό μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: ν”„λ‘œλ•μ…˜ ν™˜κ²½μ΄λΌλ©΄ React 18κ³Ό 같은 μ•ˆμ •μ μΈ 버전을 μ‚¬μš©ν•˜κ³ , React 19λŠ” 정식 릴리슀 및 μΆ©λΆ„ν•œ ν…ŒμŠ€νŠΈ 후에 λ„μž…ν•˜λŠ” 것을 ꢌμž₯ν•©λ‹ˆλ‹€. μ‹€ν—˜μ μΈ κΈ°λŠ₯ ν…ŒμŠ€νŠΈ λͺ©μ μ΄λΌλ©΄ λ¬Έμ„œν™”λ₯Ό λͺ…ν™•νžˆ ν•˜μ„Έμš”.
  • ESLint Flat Config λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ 및 νƒ€μž… 기반 κ·œμΉ™ κ°•ν™”
    • 문제점: ESLint 9.xλ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ κΈ°μ‘΄ eslintrc 섀정이 μ•„λ‹Œ Flat Config(eslint.config.js)둜의 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ΄ ν•„μš”ν•˜λ©°, νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ κ°•λ ₯ν•œ νƒ€μž… 정보λ₯Ό ν™œμš©ν•˜λŠ” λ¦°νŒ… κ·œμΉ™μ΄ μΆ©λΆ„νžˆ μ μš©λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ:
      • ESLint Flat Configuration μ‹œμŠ€ν…œμœΌλ‘œ μ „ν™˜ν•˜κ³  κΈ°μ‘΄ κ·œμΉ™λ“€μ„ μ˜¬λ°”λ₯΄κ²Œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•˜μ„Έμš”.
      • .eslintrc.cjs λ˜λŠ” eslint.config.js에 @typescript-eslint/recommended-type-checked λ˜λŠ” strict-type-checked ν”ŒλŸ¬κ·ΈμΈμ„ μΆ”κ°€ν•˜μ—¬ νƒ€μž… 정보 기반의 μ—„κ²©ν•œ λ¦°νŒ…μ„ ν™œμ„±ν™”ν•©λ‹ˆλ‹€.
      • eslint-plugin-reactλ₯Ό μ„€μΉ˜ν•˜κ³  plugin:react/recommended, plugin:react/jsx-runtime을 μΆ”κ°€ν•˜μ—¬ React μ»΄ν¬λ„ŒνŠΈ λ¦°νŒ…μ„ κ°•ν™”ν•©λ‹ˆλ‹€.
      • react-refresh/only-export-components κ·œμΉ™μ˜ μˆ˜μ€€μ„ 'warn'μ—μ„œ 'error'둜 λ³€κ²½ν•˜μ—¬ HMR(Hot Module Replacement) 문제λ₯Ό λ°©μ§€ν•©λ‹ˆλ‹€.
  • react-queryλ₯Ό @tanstack/react-query둜 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜
    • 문제점: react-query v3λŠ” 더 이상 ν™œλ°œνžˆ μœ μ§€λ³΄μˆ˜λ˜μ§€ μ•ŠμœΌλ©°, @tanstack/react-query둜 이름이 λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: react-query v3 μ˜μ‘΄μ„±μ„ μ œκ±°ν•˜κ³  @tanstack/react-query v4 λ˜λŠ” v5λ₯Ό μ„€μΉ˜ν•˜μ—¬ μ„±λŠ₯ μ΅œμ ν™”, λ²ˆλ“€ 크기 κ°œμ„ , μƒˆλ‘œμš΄ κΈ°λŠ₯ 및 더 λ‚˜μ€ νƒ€μž… 지원을 ν™œμš©ν•˜μ„Έμš”. κ΄€λ ¨ src μ½”λ“œμ˜ λ‘œμ§λ„ μƒˆλ‘œμš΄ API에 맞게 μ—…λ°μ΄νŠΈν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • TypeScript μ΅œμ‹  버전 ν™œμš© 및 엄격 λͺ¨λ“œ ν™œμ„±ν™”
    • 문제점: typescript: "^5.2.2"λ₯Ό μ‚¬μš© 쀑이며, μ—„κ²©ν•œ νƒ€μž… 검사 μ˜΅μ…˜ μ„€μ • μ—¬λΆ€λ₯Ό μ•Œ 수 μ—†μŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: TypeScriptλ₯Ό μ΅œμ‹  μ•ˆμ • 버전(예: ^5.4.x λ˜λŠ” ^5.5.x)으둜 μ—…λ°μ΄νŠΈν•˜κ³ , tsconfig.jsonμ—μ„œ strict: true, noImplicitAny: true, strictNullChecks: true λ“± μ—„κ²©ν•œ νƒ€μž… 검사 μ˜΅μ…˜μ„ ν™œμ„±ν™”ν•˜μ—¬ νƒ€μž… μ•ˆμ „μ„±μ„ κ·ΉλŒ€ν™”ν•˜μ„Έμš”.
  • @hookform/resolvers 버전 동기화
    • 문제점: react-hook-form v7.55.0κ³Ό @hookform/resolvers v5.0.1이 λͺ…μ‹œλ˜μ–΄ μžˆμ–΄ νƒ€μž… ν˜Έν™˜μ„± λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: react-hook-form v7에 맞좰 @hookform/resolvers도 μ΅œμ‹  v7 ν˜Έν™˜ λ²„μ „μœΌλ‘œ μ—…λ°μ΄νŠΈν•˜μ—¬ νƒ€μž… 뢈일치둜 μΈν•œ 잠재적인 문제λ₯Ό ν•΄κ²°ν•©λ‹ˆλ‹€.
  • use-fetch 라이브러리 κ²€ν† 
    • 문제점: use-fetch와 같은 μž‘μ€ μœ ν‹Έλ¦¬ν‹° 라이브러리 μ˜μ‘΄μ„±μ€ μœ μ§€λ³΄μˆ˜ μœ„ν—˜μ΄ 될 수 있으며, @tanstack/react-query와 κΈ°λŠ₯이 쀑볡될 수 μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: use-fetch의 ν•„μš”μ„±μ„ ν‰κ°€ν•˜κ³  @tanstack/react-query λ˜λŠ” axiosλ₯Ό λž˜ν•‘ν•˜λŠ” λ°©μ‹μœΌλ‘œ λŒ€μ²΄ν•˜μ—¬ 쒅속성을 쀄이고 μ½”λ“œμ˜ 일관성을 λ†’μ΄λŠ” 것을 κ³ λ €ν•©λ‹ˆλ‹€.
  • 핡심 dependencies의 버전 κ³ μ • 및 engines ν•„λ“œ λͺ…μ‹œ
    • 문제점: react, tailwindcss λ“± 핡심 dependencies에 캐럿(^) μ—°μ‚°μžκ°€ μ‚¬μš©λ˜μ–΄ λΉŒλ“œ 일관성을 μ €ν•΄ν•  수 있으며, Node.js 버전이 λͺ…μ‹œλ˜μ–΄ μžˆμ§€ μ•Šμ•„ 개발 ν™˜κ²½ κ°„ 뢈일치λ₯Ό μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: package.json의 핡심 dependenciesλŠ” μ •ν™•ν•œ 버전(예: 19.2.3)을 λͺ…μ‹œν•˜μ—¬ λͺ¨λ“  ν™˜κ²½μ—μ„œ λ™μΌν•œ νŒ¨ν‚€μ§€ 버전을 μ‚¬μš©ν•˜λ„λ‘ κ°•μ œν•©λ‹ˆλ‹€. λ˜ν•œ, engines.node ν•„λ“œλ₯Ό μΆ”κ°€ν•˜μ—¬ ν”„λ‘œμ νŠΈκ°€ μ§€μ›ν•˜λŠ” μ΅œμ†Œ Node.js 버전을 λͺ…μ‹œν•˜μ„Έμš”.
  • 정기적인 쒅속성 λ³΄μ•ˆ 감사 및 λ²ˆλ“€ μ‚¬μ΄μ¦ˆ λͺ¨λ‹ˆν„°λ§
    • κ°œμ„  μ œμ•ˆ: Dependabot λ˜λŠ” Renovate Bot을 μ‚¬μš©ν•˜μ—¬ 쒅속성 μ—…λ°μ΄νŠΈλ₯Ό μžλ™ν™”ν•˜κ³ , pnpm audit (λ˜λŠ” npm audit)λ₯Ό CI/CD νŒŒμ΄ν”„λΌμΈμ— ν†΅ν•©ν•˜μ—¬ λ³΄μ•ˆ 취약점을 κ°μ§€ν•˜μ„Έμš”. rollup-plugin-visualizer와 같은 λ²ˆλ“€ μ‚¬μ΄μ¦ˆ 뢄석 도ꡬλ₯Ό ν†΅ν•©ν•˜μ—¬ μ„±λŠ₯ μ €ν•˜λ₯Ό 미리 μ‹λ³„ν•©λ‹ˆλ‹€.

2. API 계측 (src/apis)

  • src/apis/axios.ts
    • νƒ€μž… μ•ˆμ „μ„± κ°•ν™”:
      • error.config에 _retry 속성을 μΆ”κ°€ν•˜λŠ” 뢀뢄에 λŒ€ν•œ λͺ…μ‹œμ μΈ νƒ€μž… ν™•μž₯(CustomAxiosRequestConfig μΈν„°νŽ˜μ΄μŠ€ μ •μ˜)이 ν•„μš”ν•©λ‹ˆλ‹€.
      • 토큰 κ°±μ‹  API 응닡(response.data.accessToken)κ³Ό catch λΈ”λ‘μ˜ refreshError에 λŒ€ν•œ νƒ€μž…μ„ λͺ…ν™•νžˆ μ •μ˜ν•©λ‹ˆλ‹€ (예: RefreshTokenResponse μΈν„°νŽ˜μ΄μŠ€, AxiosError νƒ€μž… κ°€λ“œ ν™œμš©).
    • λ¦¬νŒ©ν† λ§ 및 μœ μ§€λ³΄μˆ˜μ„± ν–₯상:
      • baseURLκ³Ό 토큰 κ°±μ‹  API URL을 ν•˜λ“œμ½”λ”©ν•˜λŠ” λŒ€μ‹  .env νŒŒμΌμ— VITE_API_BASE_URLκ³Ό 같은 ν™˜κ²½ λ³€μˆ˜λ‘œ κ΄€λ¦¬ν•˜μ—¬ μœ μ—°μ„±μ„ ν™•λ³΄ν•©λ‹ˆλ‹€.
      • accessToken, refreshToken λ¬Έμžμ—΄μ„ μƒμˆ˜λ‘œ λΆ„λ¦¬ν•˜μ—¬ μ˜€νƒ€λ₯Ό λ°©μ§€ν•˜κ³  μœ μ§€λ³΄μˆ˜μ„±μ„ λ†’μž…λ‹ˆλ‹€.
      • 토큰 μ‚­μ œ 및 둜그인 νŽ˜μ΄μ§€ λ¦¬λ‹€μ΄λ ‰μ…˜ λ‘œμ§μ„ handleAuthError와 같은 별도 μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ‘œ λΆ„λ¦¬ν•˜μ—¬ μ½”λ“œμ˜ 가독성 및 응집도λ₯Ό λ†’μž…λ‹ˆλ‹€.
  • src/apis/signup.ts
    • νƒ€μž… μ•ˆμ „μ„± κ°•ν™”: signUpUser ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” response.data의 νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€(예: SignUpResponse)λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.
    • 데이터 처리 및 μ—λŸ¬ 핸듀링 κ°œμ„ :
      • bio: "μ•ˆλ…•ν•˜μ„Έμš”. μ €λŠ” λ§€νŠœμž…λ‹ˆλ‹€."와 같이 ν•˜λ“œμ½”λ”©λœ bio ν•„λ“œμ˜ μ˜λ„λ₯Ό λͺ…ν™•νžˆ ν•˜κ³ , ν•„μš”μ— 따라 SignUpPayload에 ν¬ν•¨ν•˜κ±°λ‚˜ μƒμˆ˜λ‘œ μΆ”μΆœν•©λ‹ˆλ‹€.
      • API 호좜 μ‹€νŒ¨ μ‹œ axios.isAxiosErrorλ₯Ό μ‚¬μš©ν•˜μ—¬ ꡬ체적인 μ—λŸ¬(예: 409 Conflict, 400 Bad Request)λ₯Ό μ²˜λ¦¬ν•˜λŠ” λ‘œμ§μ„ μΆ”κ°€ν•˜μ—¬ μ‚¬μš©μžμ—κ²Œ μƒμ„Έν•œ ν”Όλ“œλ°±μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

3. μ»€μŠ€ν…€ ν›… 계측 (src/hooks)

  • src/hooks/usemoviesearch.ts - ν΄λΌμ΄μ–ΈνŠΈ μΈ‘ 성인 μ½˜ν…μΈ  필터링 λΉ„νš¨μœ¨
    • 문제점: includeAdult μ˜΅μ…˜μ— 따라 API 응닡을 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ ν•„ν„°λ§ν•˜κ³  μžˆμ–΄ λΉ„νš¨μœ¨μ μž…λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: TMDB APIλŠ” include_adult νŒŒλΌλ―Έν„°λ₯Ό μ§€μ›ν•˜λ―€λ‘œ, 이 필터링을 μ„œλ²„ μΈ‘μ—μ„œ μˆ˜ν–‰ν•˜λ„λ‘ API μš”μ²­(axios.get의 params)에 ν¬ν•¨ν•˜μ—¬ λ„€νŠΈμ›Œν¬ νŠΈλž˜ν”½ 및 ν΄λΌμ΄μ–ΈνŠΈ μ²˜λ¦¬λŸ‰μ„ μ ˆκ°ν•©λ‹ˆλ‹€.
  • src/hooks/usemoviedetail.ts - movieId νƒ€μž… μ•ˆμ „μ„± κ°•ν™”
    • 문제점: useParams<{ movieId: string }>() 이후 movieId as string으둜 νƒ€μž… 단언을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: movieIdλ₯Ό string | undefined둜 λͺ…ν™•ν•˜κ²Œ νƒ€μž…μ„ μ§€μ •ν•˜κ³ , useQuery의 enabled: !!movieId 쑰건을 ν™œμš©ν•˜λ©°, fetchMovieDetails ν•¨μˆ˜μ—μ„œλ„ 이λ₯Ό μΈμ§€ν•˜λ„λ‘ ν•˜μ—¬ νƒ€μž… 단언을 μ€„μž…λ‹ˆλ‹€.
  • src/hooks/useloginform.ts, src/hooks/usesignupform.ts - 인증 토큰 관리 둜직 쀑볡 및 μ—λŸ¬ 핸듀링
    • 문제점: localStorage.setItem("accessToken", ...) λ“± 인증 토큰 μ €μž₯ 둜직이 μ—¬λŸ¬ κ³³μ—μ„œ λ°˜λ³΅λ©λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: 이λ₯Ό λ³„λ„μ˜ μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ‚˜ AuthContext, λ˜λŠ” AuthService λͺ¨λ“ˆλ‘œ μΆ”μΆœν•˜μ—¬ 쀑앙 μ§‘μ€‘μ‹μœΌλ‘œ κ΄€λ¦¬ν•˜κ³ , axios.isAxiosErrorλ₯Ό ν™œμš©ν•œ μ—λŸ¬ 핸듀링과 ν•¨κ»˜ μ‚¬μš©μžμ—κ²Œ ν† μŠ€νŠΈ μ•Œλ¦Ό λ“±μ˜ ν˜•νƒœλ‘œ μ—λŸ¬ λ©”μ‹œμ§€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.
  • src/hooks/usecallbackpage.ts (handleIncreaseCount) - useCallback μ˜μ‘΄μ„± λ°°μ—΄ μ΅œμ ν™”
    • 문제점: handleIncreaseCount의 μ˜μ‘΄μ„± 배열에 [count]κ°€ ν¬ν•¨λ˜μ–΄ μžˆμ–΄ count λ³€κ²½ μ‹œ ν•¨μˆ˜κ°€ μž¬μƒμ„±λ˜λ©°, CountButton의 memo 효과λ₯Ό μƒμ‡„ν•©λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: setCount에 ν•¨μˆ˜ν˜• μ—…λ°μ΄νŠΈ(prevCount => prevCount + number)λ₯Ό μ‚¬μš©ν•˜μ—¬ countλ₯Ό μ˜μ‘΄μ„± λ°°μ—΄μ—μ„œ μ œκ±°ν•¨μœΌλ‘œμ¨ handleIncreaseCount의 μ°Έμ‘° μ•ˆμ •μ„±μ„ ν™•λ³΄ν•©λ‹ˆλ‹€.
  • src/hooks/usememopage.ts (handleChangeText) - useCallback 적용 κ³ λ €
    • κ°œμ„  μ œμ•ˆ: handleChangeText ν•¨μˆ˜λ„ useCallback으둜 감싸 μ°Έμ‘° μ•ˆμ •μ„±μ„ ν™•λ³΄ν•˜λ©΄, TextInput이 React.memo둜 λž˜ν•‘λ  경우 λΆˆν•„μš”ν•œ λ¦¬λ Œλ”λ§μ„ λ°©μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ „λ°˜μ μΈ μ»€μŠ€ν…€ ν›… 주석 ν’ˆμ§ˆ ν–₯상
    • κ°œμ„  μ œμ•ˆ: useLocalStorage, useMovieDetail, useMovieSearch λ“± λ³΅μž‘ν•˜κ±°λ‚˜ μ€‘μš”ν•œ λ‘œμ§μ„ λ‹΄κ³  μžˆλŠ” μ»€μŠ€ν…€ 훅에 JSDoc μŠ€νƒ€μΌμ˜ 주석을 μΆ”κ°€ν•˜μ—¬ ν›…μ˜ λͺ©μ , 인자, λ°˜ν™˜ κ°’ 등을 λͺ…ν™•νžˆ μ„€λͺ…ν•©λ‹ˆλ‹€.

4. μ»΄ν¬λ„ŒνŠΈ 및 νŽ˜μ΄μ§€ 계측 (src/components, src/pages)

  • src/App.tsx, src/main.tsx: ν‘œμ€€μ μΈ React μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ꡬ성이며, StrictMode μ‚¬μš©μ€ 쒋은 개발 μŠ΅κ΄€μž…λ‹ˆλ‹€.
  • src/components/movie-detail/detailcontent.tsx
    • μ„±λŠ₯: μ˜ν™” 상세 νŽ˜μ΄μ§€ λ°°κ²½ 이미지(movie?.poster_path)의 크기가 w500으둜 κ³ μ •λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λ‹€μ–‘ν•œ ν™”λ©΄ 크기에 맞좰 srcset λ˜λŠ” <picture> νƒœκ·Έ, λ―Έλ””μ–΄ 쿼리 등을 ν™œμš©ν•˜μ—¬ λ°˜μ‘ν˜• 이미지 기법을 μ μš©ν•΄ μ μ ˆν•œ ν•΄μƒλ„μ˜ 이미지λ₯Ό λ‘œλ“œν•˜λ„λ‘ κ³ λ €ν•©λ‹ˆλ‹€.
    • νƒ€μž…μŠ€ν¬λ¦½νŠΈ: Movie μΈν„°νŽ˜μ΄μŠ€μ˜ ν•„μˆ˜/선택 ν•„λ“œλ₯Ό API μŠ€νŽ™μ— 맞좰 λͺ…ν™•νžˆ μ„ μ–Έν•˜μ—¬ (id, title, poster_path 등은 ν•„μˆ˜) νƒ€μž… μ•ˆμ •μ„±μ„ 높이고 λΆˆν•„μš”ν•œ 널 체크λ₯Ό μ€„μž…λ‹ˆλ‹€.
  • src/components/movie/movie-item.tsx
    • μ½”λ“œ ν’ˆμ§ˆ: Itemμ΄λΌλŠ” μ»΄ν¬λ„ŒνŠΈ 이름은 뢈λͺ…ν™•ν•©λ‹ˆλ‹€. MovieList λ‚΄μ—μ„œ μ‚¬μš©λ˜λ―€λ‘œ MovieItem으둜 λ³€κ²½ν•˜μ—¬ μ˜λ„λ₯Ό λͺ…ν™•νžˆ ν•©λ‹ˆλ‹€.
  • src/components/CountButton.tsx & src/components/TextInput.tsx
    • μ„±λŠ₯: memo둜 λž˜ν•‘λ˜μ–΄ μžˆμ§€λ§Œ, <button>의 onClick 및 <input>의 onChange ν•Έλ“€λŸ¬κ°€ 인라인 ν•¨μˆ˜λ‘œ μ •μ˜λ˜μ–΄ λ§€ λ Œλ”λ§λ§ˆλ‹€ μƒˆλ‘œμš΄ ν•¨μˆ˜κ°€ μƒμ„±λ©λ‹ˆλ‹€. μ΄λŠ” memo의 효과λ₯Ό 상쇄할 수 μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: λ‚΄λΆ€ 이벀트 ν•Έλ“€λŸ¬λ₯Ό useCallback으둜 λž˜ν•‘ν•˜μ—¬ μ°Έμ‘° μ•ˆμ •μ„±μ„ ν™•λ³΄ν•©λ‹ˆλ‹€.
    • μ½”λ“œ ν’ˆμ§ˆ: 디버깅을 μœ„ν•œ console.logλŠ” ν”„λ‘œλ•μ…˜ μ½”λ“œμ—μ„œ μ œκ±°ν•˜κ±°λ‚˜ μ‘°κ±΄λΆ€λ‘œ ν™œμ„±ν™”λ˜λ„λ‘ λ³€κ²½ν•©λ‹ˆλ‹€.
    • νƒ€μž…μŠ€ν¬λ¦½νŠΈ: 인라인 ν™”μ‚΄ν‘œ ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ : voidλ₯Ό λͺ…μ‹œν•˜λŠ” 것은 λŒ€λΆ€λΆ„μ˜ 경우 λΆˆν•„μš”ν•˜λ―€λ‘œ μ œκ±°ν•˜μ—¬ 가독성을 λ†’μž…λ‹ˆλ‹€.
  • λ°˜λ³΅λ˜λŠ” μ˜ν™” μΉ΄ν…Œκ³ λ¦¬ νŽ˜μ΄μ§€ (now-playing.tsx, popular.tsx, top-rated.tsx, upcoming.tsx)
    • 쀑볡 μ½”λ“œ: 이 νŒŒμΌλ“€μ€ usePaginatedMovies 훅을 μ‚¬μš©ν•˜μ—¬ λ‹€λ₯Έ type κ°’λ§Œ 전달할 뿐 λ™μΌν•œ ꡬ쑰λ₯Ό κ°€μ§‘λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: λ‹¨μΌμ˜ μž¬μ‚¬μš© κ°€λŠ₯ν•œ μ»΄ν¬λ„ŒνŠΈ(예: MovieCategoryPage.tsx)둜 ν†΅ν•©ν•˜κ³ , type 값을 useParamsλ‚˜ useLocation을 톡해 λ™μ μœΌλ‘œ λ°›μ•„μ˜€λ„λ‘ λ¦¬νŒ©ν† λ§ν•©λ‹ˆλ‹€. src/routes/routes.tsxμ—μ„œλ„ 이 단일 μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‚¬μš©ν•˜λ„λ‘ κ°„μ†Œν™”ν•©λ‹ˆλ‹€.
  • JSX/CSS에 직접적인 '맀직 λ„˜λ²„' μ‚¬μš© μ§€μ–‘
    • 문제점: src/pages/login.tsx, src/pages/signup.tsx λ“± μ—¬λŸ¬ μ»΄ν¬λ„ŒνŠΈμ—μ„œ h-[360px], pt-[150px]와 같은 ꡬ체적인 ν”½μ…€ 값을 Tailwind CSS ν΄λž˜μŠ€μ— 직접 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: Tailwind의 κΈ°λ³Έ 간격 μŠ€μΌ€μΌμ„ μ‚¬μš©ν•˜κ±°λ‚˜, ν•„μš”ν•œ 경우 Tailwind ꡬ성 νŒŒμΌμ— μ‚¬μš©μž μ •μ˜ 값을 μΆ”κ°€ν•˜μ—¬ λ””μžμΈ μ‹œμŠ€ν…œμ˜ 일관성과 μœ μ§€λ³΄μˆ˜μ„±μ„ ν™•λ³΄ν•©λ‹ˆλ‹€.
  • src/pages/UseCallbackPage.tsx - HTML μ‹œλ§¨ν‹± ꡬ쑰 κ°œμ„ 
    • κ°œμ„  μ œμ•ˆ: κ΄€λ ¨ μžˆλŠ” μ½˜ν…μΈ λ₯Ό sectionκ³Ό 같은 HTML5 μ‹œλ§¨ν‹± μš”μ†Œλ‘œ λ¬Άμ–΄ ꡬ쑰λ₯Ό λͺ…ν™•νžˆ ν•˜κ³ , ν•„μš”ν•œ 경우 aria-labelledby와 같은 μ ‘κ·Όμ„± 속성을 μΆ”κ°€ν•˜μ—¬ 슀크린 리더 μ‚¬μš©μžμ—κ²Œ 더 λ‚˜μ€ κ²½ν—˜μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
  • src/pages/UseMemoPage.tsx
    • μ„±λŠ₯ 및 μ‚¬μš©μž κ²½ν—˜: limit 값이 컀져 수천, 수만 개의 μ†Œμˆ˜κ°€ primes 배열에 포함될 경우, λͺ¨λ“  μ†Œμˆ˜λ₯Ό DOM에 직접 λ Œλ”λ§ν•˜λŠ” 것은 λΈŒλΌμš°μ € μ„±λŠ₯ μ €ν•˜λ₯Ό μ•ΌκΈ°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: react-virtualizedλ‚˜ react-window와 같은 가상화 라이브러리λ₯Ό μ‚¬μš©ν•˜μ—¬ 화면에 λ³΄μ΄λŠ” λΆ€λΆ„λ§Œ λ Œλ”λ§ν•˜κ±°λ‚˜, νŽ˜μ΄μ§€λ„€μ΄μ…˜ κΈ°λŠ₯을 λ„μž…ν•˜μ—¬ μ‚¬μš©μž κ²½ν—˜μ„ ν–₯μƒμ‹œν‚€κ³  λ Œλ”λ§ λΆ€ν•˜λ₯Ό μ€„μ΄λŠ” 것을 κ³ λ €ν•΄λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
    • νƒ€μž… μ•ˆμ •μ„±: setLimit(Number(e.target.value)) μ½”λ“œμ—μ„œ Number(e.target.value)κ°€ NaN을 λ°˜ν™˜ν•  수 μžˆμœΌλ―€λ‘œ, parseIntλ₯Ό μ‚¬μš©ν•˜κ³  결과값이 NaNμ΄κ±°λ‚˜ μœ νš¨ν•˜μ§€ μ•Šμ€ λ²”μœ„(예: 음수)인 경우λ₯Ό μ²˜λ¦¬ν•˜λŠ” λ‘œμ§μ„ μΆ”κ°€ν•˜μ—¬ μ•ˆμ •μ„±μ„ λ†’μž…λ‹ˆλ‹€.

5. μœ ν‹Έλ¦¬ν‹° 계측 (src/utils)

  • src/utils/math.ts - isPrime ν•¨μˆ˜ 루프 쑰건 및 증감문 μ΅œμ ν™”
    • 문제점: ν˜„μž¬ isPrime ν•¨μˆ˜λŠ” μ†Œμˆ˜ νŒλ³„ μ‹œ i + i <= num 쑰건을 μ‚¬μš©ν•˜κ³  짝수 검사λ₯Ό λ°˜λ³΅ν•˜μ—¬ λΆˆν•„μš”ν•˜κ²Œ λ§Žμ€ λ°˜λ³΅μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: 루프 쑰건을 i * i <= num (즉, i <= Math.sqrt(num))으둜 λ³€κ²½ν•˜κ³ , i += 2λ₯Ό μ‚¬μš©ν•˜μ—¬ ν™€μˆ˜λ§Œ κ²€μ‚¬ν•˜λ„λ‘ μ΅œμ ν™”ν•˜μ—¬ μ„±λŠ₯을 ν–₯μƒμ‹œν‚΅λ‹ˆλ‹€.
  • src/utils/math.ts - findPrimeNumbers ν•¨μˆ˜ κ²°κ³Ό λ°˜ν™˜ 방식 κ°œμ„ 
    • 문제점: sieve.map(...).filter(...)λŠ” 쀑간 배열을 μƒμ„±ν•˜λ―€λ‘œ max 값이 맀우 클 경우 좔가적인 λ©”λͺ¨λ¦¬ μ†ŒλΉ„κ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • κ°œμ„  μ œμ•ˆ: mapκ³Ό filter λŒ€μ‹  for 루프λ₯Ό μ‚¬μš©ν•˜μ—¬ primes 배열을 직접 κ΅¬μ„±ν•˜λŠ” 것이 λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ μΈ‘λ©΄μ—μ„œ λ―Έμ„Έν•˜κ²Œ 더 효율적일 수 μžˆμŠ΅λ‹ˆλ‹€. (ν˜„μž¬ μ½”λ“œκ°€ 가독성이 μ’‹μœΌλ―€λ‘œ ν•„μˆ˜μ μΈ κ°œμ„ μ€ μ•„λ‹ˆλ©°, 극단적인 μ„±λŠ₯/λ©”λͺ¨λ¦¬ μš”κ΅¬μ‚¬ν•­μ΄ μžˆμ„ λ•Œ κ³ λ €ν•  수 μžˆμŠ΅λ‹ˆλ‹€.)

κ²°λ‘ 

이 PR은 μ „λ°˜μ μœΌλ‘œ React, TypeScript 및 λͺ¨λ˜ ν”„λ‘ νŠΈμ—”λ“œ 도ꡬ듀을 잘 ν™œμš©ν•˜κ³  μžˆλ‹€λŠ” 인상을 μ£Όμ—ˆμŠ΅λ‹ˆλ‹€. μœ„μ—μ„œ μ œμ‹œλœ μ œμ•ˆλ“€μ€ 주둜 μ„€μ •μ˜ 견고함, νƒ€μž… μ•ˆμ „μ„± κ·ΉλŒ€ν™”, λ Œλ”λ§ 및 계산 μ„±λŠ₯ μ΅œμ ν™”, 그리고 μ½”λ“œμ˜ μœ μ§€λ³΄μˆ˜μ„± 및 ν™•μž₯μ„± ν–₯상에 쀑점을 λ‘” κ²ƒμž…λ‹ˆλ‹€.

μ΄λŸ¬ν•œ κ°œμ„  사항듀을 λ°˜μ˜ν•œλ‹€λ©΄ ν”„λ‘œμ νŠΈμ˜ ν’ˆμ§ˆκ³Ό 개발 κ²½ν—˜μ„ λ”μš± 높일 수 μžˆμ„ 것이라고 μƒκ°ν•©λ‹ˆλ‹€. κΆκΈˆν•œ 점이 μžˆλ‹€λ©΄ μ–Έμ œλ“ μ§€ μ§ˆλ¬Έν•΄μ£Όμ„Έμš”.

Copy link
Collaborator

@woojo230 woojo230 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10주차도 κ³ μƒν•˜μ…¨μŠ΅λ‹ˆλ‹€

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants