스프린트 미션 9제출 - 김윤기#79
Hidden character warning
Conversation
- [PRJ-13] url path "/items/detail/{itemId}
- [PRJ-14] 목록 돌아가기 버튼 클릭시 중고 마켓 페이지로 이동
- [PRJ-15] 상품 상세 데이터는 인가된 사용자만 이용할수있도록 설정
- [PRJ-10] 상단 네이비게이션 바에 프로필 영역은 인해주세요가된 경우, 유저 정보 API를 활용해주세요 - [PRJ-11] 인가되지 않았을 경우 "로그인" 버튼이 보이게
Feat: [PRJ-2] GNB (상단 네비게이션)
- item - tag n:m - tags 유효성검사 -- FE: 배열로 -> 배열검사만안검사 -- BE: 이미 배열로 들어왔기에 배열만검사 - 간단한 상품 생성, 수정로직
- 서버 액션 -> api 라우트로 변경
- login api와 같이 httpOnly쿠키를 설정하도록 수정 후 재발급 - logout 오타 수정 및 반환값 통일화
- 로그인 토큰 시간변경 (엑세스: 30분, 리프레시: 3일) - 아이템 페이지 프롭스 내려주는것을 이제 명확히 리펙토링 - 서비스 로직 다시 만들어둔 default, cookie 패치 이용 - !! 인가되지않은 사용자 api 수정
Prj 3 epic 3 item
- 로딩 및 에러
Feat: [PRJ-4] 심화 요구 사항
Feat: [PRJ-5] Refactor Day
devbini
left a comment
There was a problem hiding this comment.
👍 전반적으로 좋았습니다.
코드량이 꽤 어마무시해서 좀 놀랐습니다. 눈이 빠져라 보긴 했는데,
중요한 부분만 보고 나머진 흘겨봐서 놓친 부분이 있을 수 있어요.
전체적으로 비동기/동기 처리에 대해선 거의 마스터했다 보여져요. await는 물론 Query 사용하는 모습도 인상적이었고, 몇가지 놓칠 수 있을법한? 애들만 코멘트들을 남겨놨어요.
마지막으로 드리고 싶은 말씀은, 서버를 너무 믿지 말라 하고 싶네요 🤣
클라이언트에서 던지는 값, 서버쪽에서 던지는 값을 나눴다 해도, 데이터 무결성이 저하될 수 있음을 인지하고 예외처리나 롤백 부분을 조금 더 신경쓰면 좋을 듯 합니다.
고생하셨습니다 :D
| getItems: (keyword, orderBy, page) => | ||
| defaultFetch( | ||
| `/api/items?limit=5&page=1&keyword=${searchParams}&orderBy=recent`, | ||
| `/api/items?limit=5&page=${page}&keyword=${keyword}&orderBy=${orderBy}`, |
There was a problem hiding this comment.
☕ Thinking...
아마 기본 요구사항이었을 것 같긴 합니다.
다만.. 다른 건 문제가 없는데 조금 마음에 걸렸던 게 limit를 강제로 5로 잡아두셔서, 나중에 이것도 매개변수로 받을 수 있도록 하면 사용성이 더 좋아지지 않을까 하는 욕심이 드네요ㅎㅎ
| queryClient.setQueryData(["item-status", itemId], context.previousStatus); | ||
| } | ||
|
|
||
| console.error("좋아요 실패:", error) |
There was a problem hiding this comment.
☕ Thinking...
console 로그도 좋은데, 저희 지난번 멘토링 때 살짝 봤던
toast라이브러리 라던지, 아니면 alert로 사용자에게 에러 여부를 알려주면 어떨까 싶어요.
다른 곳 보니까, context로 내려받아 사용하고 계신 openDialog 이 있던데, 이걸 사용 해 보면 어떨까요?
| const currentLikeCount = Number(itemQuery.data?.data?.likeCount ?? initialLikeCount ?? 0); | ||
| const currentIsLiked = statusQuery.data?.data?.isLiked ?? DEFAULT_IS_LIKED; | ||
|
|
||
| const likeMutation = useMutation({ |
There was a problem hiding this comment.
👍 Good Point
매번 느끼는건데, 동기/비동기 관련된 부분이라 하죠? 낙관적 락 비관적 락 등 이런 테크닉을 잘 쓰는 개발자일 수록 사용자들이 행복해하는 것 같아요.
아래 로직을 보면 롤백 부분도 나름 잘 대비 해 놓으셨고..
const previousItems = queryClient.getQueryData(['item', itemId]);
const previousStatus = queryClient.getQueryData(['like-status', itemId]);
새로운 변수를 항상 선언해서 메모리를 잡아먹는 건 조금 아쉽긴 하지만 어쩔 수 없는거겠죠?
사용자 가용성을 침해하지 않는 선에서 잘 사용하고 계신 것 같습니다.
앞으로도 이런 테크닉은 종종 써 먹으시면 좋을 것 같아요!
| const results = useQueries({ | ||
| queries: [ | ||
| // 공개 데이터 좋아요 갯수 | ||
| { queryKey: ["item", itemId], queryFn: () => itemService.getItemById(itemId) }, |
There was a problem hiding this comment.
☕ Thinking...
쿼리 아이템..을 사용할 때 말이죠, 사실 지금도 큰 문제는 없지만
앞으로 유지보수할 때 다른 방법도 있어서 소개 한번 시켜드릴게요.
이 방식으로 진행하면, 휴먼 에러나 키 구조 변경 등 사소한 이슈에 쉽게 대응할 수 있지 않을까 싶어요.
| queryClient.setQueryData(["item", itemId], context.previousItems); | ||
| } | ||
| if (context?.previousStatus) { | ||
| queryClient.setQueryData(["item-status", itemId], context.previousStatus); |
There was a problem hiding this comment.
🚩 Red Flag
코드량이 많아서 제가 못 본 거일 수 있는데, 롤백에서 사용하는 쿼리 키 값이 지금 위 Mutate에서 사용한 키가 맞는지 확인 해 주세요.
지금 제 눈에는 위 Mutate 키는 like-status인데, 롤백은 item-status 여서요!
|
|
||
| const itemData = await itemService.getItems(keyword, orderBy, page) | ||
|
|
||
| const items = itemData.data.items; |
There was a problem hiding this comment.
☕ Thinking..
Dialog 만들어 둔 김에, 이런 데이터 읽어오는 부분에 try-catch를 걸어주는 건 어떨까요? 사용자가 예측하지 못한 버그 결과를 보면 안 되니까요!
요구사항
기본 요구사항
공통
로그인/회원가입 페이지
로그인 페이지
회원가입 페이지
로그인, 회원가입 페이지 공통
GNB
상품 상세 페이지
- [x] 상품에 대한 댓글 조회도 가능합니다.
심화 요구사항
로그인 및 회원가입 페이지 공통
PC: 1200px 이상
Tablet: 744px 이상 ~ 1199px 이하
Mobile: 375px 이상 ~ 743px 이하
375px 미만 사이즈의 디자인은 고려하지 않습니다
유저 기능
React-Query로 마이그레이션
로딩 및 에러 핸들링
상품 데이터 캐싱 및 업데이트
- [x] 상품 목록 페이지에서 데이터의 실시간 업데이트를 위해 적절한 Query Refresh 설정을 적용합니다.
멘토에게
-아직 미흡한 부분이 많습니다.