Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸ’­ λ©˜ν† λ‹˜ 리뷰 #83

Open
wants to merge 771 commits into
base: review-branch
Choose a base branch
from
Open

Conversation

eunjju2
Copy link
Collaborator

@eunjju2 eunjju2 commented Dec 1, 2024

πŸ› οΈ μ„œλΉ„μŠ€ μš”μ•½

  • μ‚¬μš©μžμ™€ μ‚¬μ—…μžκ°€ ν•˜λ‚˜μ˜ ν”Œλž«νΌμ—μ„œ μ—°κ²°λ˜λŠ” μŠ€ν„°λ””λ£Έ μ˜ˆμ•½ μ„œλΉ„μŠ€
  • μ‚¬μš©μžλŠ” μœ„μΉ˜ 및 μž₯μ†Œ 검색을 톡해 μŠ€ν„°λ””λ£Έμ„ μ°Ύκ³  μ˜ˆμ•½ 및 결제λ₯Ό ν•  수 있으며, μ‚¬μ—…μžλŠ” 본인의 μŠ€ν„°λ””λ£Έκ³Ό μ˜ˆμ•½μžλ₯Ό 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“ μš”κ΅¬ 사항과 κ΅¬ν˜„ λ‚΄μš©

  1. 둜그인 및 νšŒμ›κ°€μž…, 사업μž₯ 등둝 및 μŠ€ν„°λ””λ£Έ 상세 보기 - μ΅œμ„±λ Ή
  2. 지도 및 μž₯μ†Œ 검색, μ˜ˆμ•½ 및 결제, 1:1 문의 - μ΄μ€μˆ˜
  3. μ‚¬μš©μž & μ‚¬μ—…μž νšŒμ› 관리, 사업μž₯ 및 μ˜ˆμ•½ 관리, μ‹€μ‹œκ°„ μ•Œλ¦Ό - μ‘°ν˜„μ§„

πŸ“ μž‘μ—… ν˜„ν™©

  • ν”„λ‘ νŠΈμΈ‘ νŽ˜μ΄μ§€λ³„ λ§ˆν¬μ—…μ€ 마무리된 μƒνƒœμž…λ‹ˆλ‹€. api μ—°κ²°ν•˜λ©΄μ„œ μžμž˜ν•œ λΆ€λΆ„λ§Œ μˆ˜μ •μ΄ 이루어지면 될 것 κ°™μŠ΅λ‹ˆλ‹€.

  • λ°±μ—”λ“œμͺ½ μ„œλ²„ 배포가 λΌμ„œ ν˜„μž¬ κ°€λŠ₯ν•œ apiλ₯Ό μ—°κ²°ν•΄μ„œ ν…ŒμŠ€νŠΈν•΄λ³΄κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‹€λ§Œ μ™„λ²½νžˆ 배포된 것은 μ•„λ‹ˆμ–΄μ„œ ν…ŒμŠ€νŠΈμ— μ‹œκ°„μ΄ 쑰금 μ†Œμš”λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

    μ§€κΈˆ ν…ŒμŠ€νŠΈν•΄λ³΄κ³  μžˆλŠ” νŽ˜μ΄μ§€λŠ”

    • μ‚¬μ—…μž / μ‚¬μš©μž νšŒμ›κ°€μž… νŽ˜μ΄μ§€
    • μ‚¬μ—…μž / μ‚¬μš©μž 둜그인 νŽ˜μ΄μ§€
    • μ‚¬μ—…μž / μ‚¬μš©μž λ§ˆμ΄νŽ˜μ΄μ§€(λ‘œκ·Έμ•„μ›ƒ 포함)
    • λ©”μΈνŽ˜μ΄μ§€
    • 사업μž₯ μƒμ„ΈνŽ˜μ΄μ§€

    μ •λ„μž…λ‹ˆλ‹€. μ€‘κ°„λ°œν‘œλ•ŒκΉŒμ§€ ν•΄λ‹Ή νŽ˜μ΄μ§€λ“€μ€ μ΅œλŒ€ν•œ κ΅¬ν˜„μ„ 끝낼 μ˜ˆμ •μž…λ‹ˆλ‹€.

πŸ’¬ 리뷰 μ‹œμ— 참고사항

  • 둜컬 ꡬ동 μ‹œ npm install μ‹€ν–‰ν•˜μ…”μ•Ό ν•©λ‹ˆλ‹€.
  • .env νŒŒμΌμ— 각 킀값을 λ„£μ–΄μ•Ό ν•˜λŠ”λ° DM으둜 μš”μ²­ν•΄μ£Όμ‹œλ©΄ λ°”λ‘œ μ•Œλ €λ“œλ¦¬κ² μŠ΅λ‹ˆλ‹€.
  • 지도 이용 μ‹œ λΈŒλΌμš°μ €μ—μ„œ ν˜„μž¬ μœ„μΉ˜ μˆ˜μ§‘μ— κ΄€ν•œ κΆŒν•œμ΄ λ™μ˜λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • 각 νŽ˜μ΄μ§€ κ²½λ‘œλŠ” Rounter.tsx μ°Έκ³ ν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€.

πŸ’¬Β μž‘μ—…λ‚΄μ—­μ— λŒ€ν•œ μ„€λͺ… & κΆκΈˆν•œ 점

  • typings ν΄λ”μ—λŠ” κ³΅ν†΅μœΌλ‘œ μ‚¬μš©ν•˜λŠ” νƒ€μž…μ„ 정리해두고, constants ν΄λ”μ—λŠ” κ³΅ν†΅μœΌλ‘œ μ‚¬μš©ν•˜λŠ” μ—λŸ¬ λ¬Έκ΅¬λ‚˜ placeholderλ₯Ό μ •λ¦¬ν•΄λ‘μ—ˆμŠ΅λ‹ˆλ‹€.
  • κ³΅ν†΅μœΌλ‘œ μ‚¬μš©λ λ§Œν•œ μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ“€μ€ λ”°λ‘œ utils ν΄λ”λ‘œ λΉΌμ„œ, 쀑볡 μ½”λ“œλ₯Ό 쀄이고 μ΅œλŒ€ν•œ 같이 ν™œμš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ μ§„ν–‰ν–ˆμŠ΅λ‹ˆλ‹€.
  • apiλ₯Ό 각 νŽ˜μ΄μ§€λ³„λ‘œ μƒμ„±ν•˜μ§€ μ•Šκ³  κΈ°λŠ₯λ³„λ‘œ λΆ„λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.
  • axiosλ₯Ό λͺ¨λ“ˆν™”ν•΄μ„œ, 쀑볡 μ½”λ“œλ₯Ό λ°©μ§€ν•˜κ³ μž ν–ˆμŠ΅λ‹ˆλ‹€.
    • μ§€λ‚œ ν”„λ‘œμ νŠΈμ—μ„œ axios κ΄€λ ¨ μ½”λ“œλ₯Ό μž‘μ„±ν•  λ•Œ, λ™μΌν•œ 역할을 ν•˜λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό 각각 λ”°λ‘œ λ§Œλ“€κ³  인증이 ν•„μš”ν•œ μš”μ²­μ—λŠ” 헀더에 토큰 λ„£λŠ” μ½”λ“œλ₯Ό 맀번 μž‘μ„±ν•˜λŠ” λ“± 쀑볡 μ½”λ“œκ°€ 많이 λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ μ΄λ²ˆμ— λͺ¨λ“ˆν™”λ₯Ό μ‹œλ„ν•΄λ΄€μŠ΅λ‹ˆλ‹€!

    • AxiosInstanceλ₯Ό μƒμ„±ν•˜μ—¬ 같이 μ‚¬μš©

    • 인증이 ν•„μš” μ—†λŠ” κ²½μš°μ—λŠ” defaultInstanceλ₯Ό μ‚¬μš©ν•˜κ³ , 인증이 ν•„μš”ν•œ κ²½μš°μ—” authInstanceλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

    • authInstance 응닡 μΈν„°μ…‰ν„°μ—μ„œλŠ” 401μ—λŸ¬κ°€ λ°œμƒν•  경우 refresh 토큰을 κ°±μ‹ ν•˜λŠ” μš”μ²­μ„ λ³΄λƒ…λ‹ˆλ‹€.

      POST /reissue λŠ” 쿠킀에 μžˆλŠ” refresh ν† ν°μœΌλ‘œ λ¦¬ν”„λ ˆμ‹œκ°€ λ§žλŠ”μ§€, μœ νš¨ν•œμ§€, DB에 μ €μž₯λ˜μ–΄ μžˆλŠ”μ§€λ₯Ό κ²€μ‚¬ν•œ ν›„ accessTokenκ³Ό refreshToken을 μž¬μƒμ„±ν•©λ‹ˆλ‹€.

      refresh 토큰이 μœ νš¨ν•˜λ©΄(200) μƒˆλ‘œ λ°œκΈ‰λœ accessToken을 λ‹€μ‹œ localStorage에 μ €μž₯ν•˜κ³  κΈ°μ‘΄ μš”μ²­μ„ μž¬μ‹œλ„ν•©λ‹ˆλ‹€.

      μœ νš¨ν•˜μ§€ μ•ŠμœΌλ©΄ λ‘œκ·Έμ•„μ›ƒ μ²˜λ¦¬λ©λ‹ˆλ‹€.

    • authInstance μš”μ²­ μΈν„°μ…‰ν„°μ—λŠ” μš”μ²­μ΄ μ„œλ²„μ— μ „μ†‘λ˜κΈ° 전에 accessToken을 가져와 헀더에 인증 κΆŒν•œμ„ μΆ”κ°€ν•©λ‹ˆλ‹€. 이후 μˆ˜μ •λœ configλ₯Ό λ°˜ν™˜ν•΄μ„œ 이 μ„€μ •λŒ€λ‘œ μš”μ²­μ΄ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€.

    • errorInterceptor λ₯Ό 톡해 μ—λŸ¬λ₯Ό μ‰½κ²Œ 관리할 수 μžˆλ„λ‘ ν–ˆμŠ΅λ‹ˆλ‹€. api μš”μ²­ ν•¨μˆ˜μ— 적힐 try-catch문을 μƒλž΅ν•  수 μžˆμ–΄ api ν•¨μˆ˜λ„ κ°„κ²°ν•˜κ²Œ μž‘μ„±ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

개인적으둜 κΆκΈˆν•œ 점

  • μ‘°ν˜„μ§„

dataκ°€ undefined일 수 μžˆλ‹€λŠ” μ—λŸ¬κ°€ 뜰 λ•Œ κ·Έκ±Έ μ–΄λ–€ μ‹μœΌλ‘œ ν•΄κ²°ν•΄μ•Ό 쒋을지 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€.

// μ œκ°€ μ‚¬μš©ν•œ 방식
{
  data?.businessName || (
    <p className="text-2xl">λ‹‰λ„€μž„μ„ 뢈러올 수 μ—†μŠ΅λ‹ˆλ‹€.</p>
  );
}

// 쑰건문 μ‚¬μš©
if (!data) {
  return <p>쑰회 μ‹€νŒ¨</p>;
}

// λ…Όλ¦¬μ—°μ‚°μž μ‚¬μš©
{
	data && ~~
}

μ €λŠ” HostInfo.tsx, UserInfo.tsx λ“±μ˜ νŒŒμΌμ—μ„œ undefined일 수 μžˆλ‹€λŠ” μ—λŸ¬κ°€ λ°œμƒν•˜λ©΄ 첫 번째 λ°©μ‹μ΄λ‚˜ μ„Έ 번째 방식을 주둜 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.
undefinedλ₯Ό μ œκ±°ν•  수 μžˆλŠ” 방법이 μ—¬λŸ¬ κ°œκ°€ μžˆλŠ”λ° μ–΄λ–€ 방식이 κ°€μž₯ μ μ ˆν•œμ§€,
그리고 undefinedλ₯Ό 보톡 μ»΄ν¬λ„ŒνŠΈμͺ½μ—μ„œ κ±ΈλŸ¬λ‚΄λŠ”μ§€, μ•„λ‹ˆλ©΄ api ν•¨μˆ˜λ‚˜ hookμ—μ„œ λ¨Όμ € κ±ΈλŸ¬λ‚Έ 데이터λ₯Ό μ»΄ν¬λ„ŒνŠΈμ—μ„œ μ‚¬μš©ν•˜λŠ”μ§€ κΆκΈˆν•©λ‹ˆλ‹€!

  • μ΄μ€μˆ˜

API 톡신 μ‹œ, μ„œλ²„μ—μ„œ λ³΄λ‚΄μ£ΌλŠ” μ—λŸ¬ status codeλ₯Ό 기반으둜 errorInterceptorμ—μ„œ 뢄리해 μ²˜λ¦¬ν•˜κ³  μžˆλŠ”λ°, 각 μ—λŸ¬λ₯Ό μ–΄λ–»κ²Œ μ²˜λ¦¬ν•΄μ•Ό 할지 아직 감이 μ•ˆ μ˜΅λ‹ˆλ‹€. κ³΅ν†΅μœΌλ‘œ μ—λŸ¬ 처리λ₯Ό ν•œ λ²ˆμ— ν•˜λŠ” 방식이 λ‚˜μ„μ§€, μ•„λ‹ˆλ©΄ 각 API μš”μ²­ λ‘œμ§μ—μ„œ μ—λŸ¬λ₯Ό κ°œλ³„μ μœΌλ‘œ ν•Έλ“€λ§ν•˜λŠ” 게 더 λ‚˜μ€ 방법인지 κ³ λ―Όμž…λ‹ˆλ‹€!

@eunjju2 eunjju2 self-assigned this Dec 1, 2024
Copy link

@devpang20 devpang20 left a comment

Choose a reason for hiding this comment

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

πŸ‘ 잘된 점

  • 규λͺ¨ λ§žμΆ°μ„œ 적절히 λ‚˜λˆˆ 폴더 ꡬ쑰
  • axios 인터셉터λ₯Ό ν†΅ν•œ λͺ¨λ“ˆν™”
  • 곡톡 μ»΄ν¬λ„ŒνŠΈ 뢄리, μœ ν‹Έ ν•¨μˆ˜ μž¬μ‚¬μš©

πŸ› οΈ κ°œμ„ ν•  점

  1. μ—λŸ¬μ²˜λ¦¬ κ°•ν™”, 곡톡 μ—λŸ¬μ™€ κ°œλ³„ μ—λŸ¬λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” ꡬ쑰둜 λ³€κ²½(μ½”λ“œ μ½”λ©˜νŠΈ 1-n μ°Έκ³ )
  • λŒ€λΆ€λΆ„μ˜ μ—λŸ¬λŠ” 곡톡 처리둜 ν•΄κ²°
  • νŠΉλ³„ν•œ μ²˜λ¦¬κ°€ ν•„μš”ν•œ 경우만 κ°œλ³„ APIμ—μ„œ 처리
  • μ½”λ“œ 쀑볡을 μ΅œμ†Œν™”ν•˜λ©΄μ„œλ„ μœ μ—°ν•œ μ—λŸ¬ 처리 κ°€λŠ₯
  1. μ»€μŠ€ν…€ 훅을 ν†΅ν•œ 데이터 처리 둜직 뢄리(μ½”λ“œ μ½”λ©˜νŠΈ 2-n μ°Έκ³ )

데이터 흐름이 λͺ…확해짐

  • API β†’ μ»€μŠ€ν…€ ν›… β†’ μ»΄ν¬λ„ŒνŠΈ
  • undefined μ²˜λ¦¬κ°€ μ»€μŠ€ν…€ ν›…μ—μ„œ 이루어짐

μ»΄ν¬λ„ŒνŠΈ μ±…μž„μ΄ 뢄리됨

  • 데이터 fetching은 μ»€μŠ€ν…€ ν›…μ—μ„œ
  • UI λ Œλ”λ§μ€ μ»΄ν¬λ„ŒνŠΈμ—μ„œ

μ—λŸ¬ μ²˜λ¦¬κ°€ 체계적

  • λ‘œλ”©/μ—λŸ¬/빈 μƒνƒœ μ²˜λ¦¬κ°€ λͺ…확함
  • μ‚¬μš©μžμ—κ²Œ μ μ ˆν•œ ν”Όλ“œλ°± 제곡

νƒ€μž… μ•ˆμ •μ„± 확보

  • μ»΄ν¬λ„ŒνŠΈμ—μ„œλŠ” 이미 νƒ€μž…μ΄ 보μž₯된 데이터 μ‚¬μš©
  • undefined 체크 λΆˆν•„μš”
    이런 λ°©μ‹μœΌλ‘œ κ΅¬ν˜„ν•˜λ©΄ μ½”λ“œκ°€ 더 μ•ˆμ •μ μ΄κ³  μœ μ§€λ³΄μˆ˜ν•˜κΈ° μ‰¬μ›Œμ§ˆ 것 κ°™μŠ΅λ‹ˆλ‹€.

좔가적인 μΆ”μ²œ

export interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

export interface ApiError {
  code: string;
  message: string;
  status: number;
}

// API μƒνƒœ μ½”λ“œ μƒμˆ˜ν™”
export const API_STATUS = {
  SUCCESS: 200,
  UNAUTHORIZED: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  SERVER_ERROR: 500,
} as const;

// μ—λŸ¬μ²˜λ¦¬ μƒμˆ˜ν‚€μ›Œλ“œ 이용
switch (status) {
  case API_STATUS.UNAUTHORIZED:
    return '둜그인이 ν•„μš”ν•©λ‹ˆλ‹€.';
  case API_STATUS.FORBIDDEN:
    return 'μ ‘κ·Ό κΆŒν•œμ΄ μ—†μŠ΅λ‹ˆλ‹€.';
  case API_STATUS.NOT_FOUND:
    return 'μš”μ²­ν•˜μ‹  정보λ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.';
  case API_STATUS.SERVER_ERROR:
    return 'μ„œλ²„ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.';
  default:
    return 'μ•Œ 수 μ—†λŠ” 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.';

폴더ꡬ쑰 μ°Έκ³  자료

  • FSD λΌλŠ” ꡬ쑰가 μžˆλ‹€λŠ” 것도 μ°Έκ³ , ν˜„μž¬ 유λͺ…ν•œ 디렉토리 λΆ„λ₯˜ 기쀀이라 참고정도 해보면 μ’‹μŒ. μ˜μƒμ—λ„ λ‚˜μ˜€μ§€λ§Œ 디렉토리 ꡬ쑰 λΆ„λ₯˜μ— 정닡은 μ—†μŒ. λΆˆνŽΈν• λ•Œ κ°œμ„ μ„ μœ„ν•΄ λ‚˜λˆ„λŠ”κ²Œ μ •λ‹΅.
    https://www.youtube.com/watch?v=64Fx5Y1gEOA

src/apis/index.ts Show resolved Hide resolved
return response.data;
};

// 리뷰 μž‘μ„±

Choose a reason for hiding this comment

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

  • 1-2 κ°œλ³„ μ—λŸ¬ 처리의 경우 μ•„λž˜μ™€ 같이 μ²˜λ¦¬ν•˜λ©΄ λ©λ‹ˆλ‹€.
export const postReview = async (data: ReviewData): Promise<Review> => {
  try {
    const response = await authInstance.post('/api/v1/review', data);
    return response.data;
  } catch (error) {
    // 리뷰 μž‘μ„± μ‹œ νŠΉλ³„νžˆ μ²˜λ¦¬ν•΄μ•Ό ν•˜λŠ” μ—λŸ¬λ§Œ μ—¬κΈ°μ„œ 처리
    if (error.response?.status === 400) {
      throw new Error('리뷰 λ‚΄μš©μ„ ν™•μΈν•΄μ£Όμ„Έμš”.');
    }
    // λ‚˜λ¨Έμ§€λŠ” 곡톡 μ—λŸ¬ 처리둜 μ „νŒŒ
    throw error;
  }
};

createdAt: '2024-11-12T14:00:00',
},
];

Choose a reason for hiding this comment

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

  1. data undefined μ—λŸ¬ 처리
    2-1 μ»€μŠ€ν…€ hooks λ„μž…
  • src/hooks/useWorkplaceReview.ts 생성
import { useQuery } from '@tanstack/react-query';
import { ReviewData } from '../types';

export const useWorkplaceReview = (workplaceId: string) => {
  const { data, isLoading, error } = useQuery({
    queryKey: ['workplaceReview', workplaceId],
    queryFn: () => getWorkplaceReview(workplaceId),
    retry: 1,
  });

  return {
    reviews: data ?? [], // undefined일 경우 빈 λ°°μ—΄ λ°˜ν™˜
    isLoading,
    error: error as Error | null,
  };
};
  • 2-2 hooks λ„μž… ν›„ WorkPlaceReview μˆ˜μ •
import { useWorkplaceReview } from '@/hooks/useWorkplaceReview';

const WorkPlaceReview = ({ workplaceId }: { workplaceId: string }) => {
  const { reviews, isLoading, error } = useWorkplaceReview(workplaceId);

  if (isLoading) {
    return (
      <div className='w-custom flex justify-center'>
        <p>리뷰λ₯Ό λΆˆλŸ¬μ˜€λŠ” 쀑...</p>
      </div>
    );
  }

  if (error) {
    return (
      <div className='w-custom flex justify-center'>
        <p className='text-subfont'>리뷰λ₯Ό 뢈러올 수 μ—†μŠ΅λ‹ˆλ‹€.</p>
      </div>
    );
  }

  if (reviews.length === 0) {
    return (
      <div className='w-custom flex justify-center'>
        <p className='text-subfont'>μž‘μ„±λœ 리뷰가 μ—†μŠ΅λ‹ˆλ‹€.</p>
      </div>
    );
  }

  return (
    <div className='w-custom'>
      {reviews.map((item) => (
        <div
          key={item.reviewId}
          className='border-b border-subfont py-[16px] last:border-none'
        >
          <ReviewComponent review={item} />
        </div>
      ))}
    </div>
  );
};

createdAt: string;
};
}

Choose a reason for hiding this comment

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

  • 2-3 ReviewComponentμ—μ„œμ˜ 데이터 처리
interface ReviewComponentProps {
  review: ReviewData;
}

const ReviewComponent = ({ review }: ReviewComponentProps) => {
  // reviewλŠ” 이미 νƒ€μž…μ΄ 보μž₯된 μƒνƒœ
  const { userName, reviewRating, content, createdAt } = review;

  return (
    <div>
      <h3>{userName}</h3>
      <div>{reviewRating}</div>
      <p>{content}</p>
      <span>{createdAt}</span>
    </div>
  );
};

Copy link

@devpang20 devpang20 left a comment

Choose a reason for hiding this comment

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

tanstack-query 에 λŒ€ν•΄μ„œ μΆ”κ°€μ μœΌλ‘œ 리뷰 λ‹¬μ•˜μŠ΅λ‹ˆλ‹€.

Comment on lines 1 to 32
import { getPossibleTime } from '@apis/workplace';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { PossibleTime } from '@typings/types';

type ModifyDateType = { studyRoomId: number; checkDate: Date };

export const useGetPossibleTime = (studyRoomId: number, checkDate: Date) => {
const { data, isLoading, isError } = useQuery<PossibleTime>({
queryKey: ['studyroomDetail', studyRoomId, checkDate],
queryFn: () => getPossibleTime(studyRoomId, checkDate),
});

return { data: (data ?? {}) as PossibleTime, isLoading, isError };
};

export const usePossibleTimeMutation = () => {
const queryClient = useQueryClient();

return useMutation<PossibleTime, Error, ModifyDateType>({
mutationFn: ({ studyRoomId, checkDate }) =>
getPossibleTime(studyRoomId, checkDate),
onSuccess: (_, variables) => {
const { studyRoomId, checkDate } = variables;
queryClient.invalidateQueries({
queryKey: ['studyroomDetail', studyRoomId, checkDate],
});
},
onError: (error) => {
console.log(error);
},
});
};

Choose a reason for hiding this comment

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

useGetPossibleTime의 경우 데이터 μ‘°νšŒκ°€ λͺ©μ μœΌλ‘œ λ³΄μž„. λͺ©μ μ— λ§žλŠ” λ©”μ„œλ“œ μ‚¬μš©μœΌλ‘œ μ½”λ“œ κ°„μ†Œν™”

  • ν˜„μž¬ useMutationμ—μ„œ GET μš”μ²­μ„ μ‚¬μš©ν•˜κ³  μžˆμ–΄ 역할이 λ§žμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • useMutation은 주둜 데이터 생성(POST), μˆ˜μ •(PUT/PATCH), μ‚­μ œ(DELETE)와 같은 μ„œλ²„μ˜ μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” μž‘μ—…μ— μ‚¬μš©λ©λ‹ˆλ‹€.
  • 필터링 쑰건이 변경될 λ•ŒλŠ” useQuery의 queryKeyλ₯Ό λ³€κ²½ν•˜μ—¬ μžλ™μœΌλ‘œ 데이터λ₯Ό μ‘°νšŒν•˜κ²Œ ν•˜λŠ” 것이 더 νš¨μœ¨μ μž…λ‹ˆλ‹€. κ·Έλ ‡κ²Œ 되면 invalidateQueries μ—­μ‹œ μ‚¬μš©ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.
import { getPossibleTime } from '@apis/workplace';
import { useQuery } from '@tanstack/react-query';
import { PossibleTime } from '@typings/types';

export const useGetPossibleTime = (studyRoomId: number, checkDate: Date) => {
  const { data, isLoading, isError } = useQuery<PossibleTime>({
    queryKey: ['studyroomDetail', studyRoomId, checkDate],
    queryFn: () => getPossibleTime(studyRoomId, checkDate),
    enabled: !!studyRoomId && !!checkDate,
  });

  return { 
    data: (data ?? {}) as PossibleTime, 
    isLoading, 
    isError 
  };
};

λ³€κ²½ μΆ”μ²œλ‘œμ§ μ„€λͺ…

  • useMutation, λΆˆν•„μš”ν•œ invalidateQueries 제거
  • queryKey에 studyRoomId와 checkDateλ₯Ό ν¬ν•¨μ‹œμΌœμ„œ 이 값듀이 변경될 λ•Œλ§ˆλ‹€ μžλ™μœΌλ‘œ μƒˆλ‘œμš΄ 데이터λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.

useQuery, useMutation μ‚¬μš© 정리

useQuery μ‚¬μš© μ‹œμ 

  • 데이터 쑰회 (GET)
  • ν•„ν„°λ§λœ 데이터 쑰회
  • νŽ˜μ΄μ§€λ„€μ΄μ…˜
  • μ‹€μ‹œκ°„ 데이터 폴링

useMutation μ‚¬μš© μ‹œμ 

  • 데이터 생성 (POST)
  • 데이터 μˆ˜μ • (PUT/PATCH)
  • 데이터 μ‚­μ œ (DELETE)
  • μ„œλ²„μ˜ μƒνƒœλ₯Ό λ³€κ²½ν•˜λŠ” μž‘μ—…

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ꢁ금증이 λͺ…ν™•ν•˜κ²Œ ν•΄κ²°λμŠ΅λ‹ˆλ‹€, κ°μ‚¬ν•©λ‹ˆλ‹€!! λ¦¬νŒ©ν† λ§μ— λ°˜μ˜ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€ :)

JOEIH and others added 21 commits December 6, 2024 19:33
✨ Feat : μˆ˜μ • νŽ˜μ΄μ§€ κΈ°λŠ₯ κ΅¬ν˜„ 1μ°¨
✨ Feat, ♻️ Refactor : 지도 κ°œμ„  및 μ½”λ“œ 리뷰 λ¦¬νŒ©ν† λ§ 적용
♻️ Refactor : 지도 및 검색, μƒμ„ΈνŽ˜μ΄μ§€ κ°œμ„ 
eunjju2 and others added 30 commits January 14, 2025 22:06
♻️ Refactor : S3 이미지, 토큰, μ±„νŒ… κ°œμ„ 
♻️ Refactor : μ±„νŒ… 읽음 처리 κ°œμ„ 
♻️ Refactor : μ±„νŒ… URL μˆ˜μ •
♻️ Refactor : λ§žμΆ€ν˜• μΆ”μ²œ μ„œλ²„ μ•ˆλ  μ‹œ μž¬μš”μ²­ 막도둝 κ°œμ„ 
πŸ”§ Fix : μ˜ˆμ•½ μ‹œκ°„ 선택, 검색 μš”μ²­ 버그 κ°œμ„ 
πŸ—‘οΈ Chore : μ„œλ²„ 확인을 μœ„ν•œ log μΆ”κ°€
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.

4 participants