-
Notifications
You must be signed in to change notification settings - Fork 3
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
[Feat] 다른 유저 프로필 보기 #160
The head ref may contain hidden characters: "150-feat-\uB2E4\uB978-\uC720\uC800-\uD504\uB85C\uD544-\uBCF4\uAE30"
[Feat] 다른 유저 프로필 보기 #160
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM !
setIsOpenProfileCard(true); | ||
}; | ||
|
||
useEffect(() => {}, [commentPositionTop]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 꼭 필요한건가요?
@@ -84,14 +100,19 @@ export default forwardRef<HTMLDivElement, CommentProps>(function Comment({ cardI | |||
|
|||
const handleClickReport = () => {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아무 동작도 안하는 함수인듯 한데 필요한가요?
const { data, refetch } = useQuery<PostCardListResponseData>({ | ||
queryKey: ['postData', cardId], | ||
queryFn: () => getPostDetail(cardId), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const { data, refetch } = useQuery<PostCardListResponseData>({ | |
queryKey: ['postData', cardId], | |
queryFn: () => getPostDetail(cardId), | |
const { data: 여기 네이밍해서 사용하는게 더 좋을거같기도 해요, refetch } = useQuery<PostCardListResponseData>({ | |
queryKey: ['postData', cardId], | |
queryFn: () => getPostDetail(cardId), |
if (!userData) { | ||
return toast.error('로그인이 필요합니다.'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
로그인이 필요하면 바로 모달로 연결해주는건 어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미 모달 열려있는 상태에서 비회원 유저가 댓글 쓸 때의 상황이라 사용자한테 불편할 것 같아요!
} | ||
}, [isOpenProfileCard, userId, refetch, positionTop, isAboveProfile]); | ||
|
||
return positionTop && positionTop === 0 ? null : ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return positionTop && positionTop === 0 ? null : ( | |
return positionTop && positionTop === 0 ? null : ( |
여기서 positionTop이 없으면 그냥 null처리 하셔서 아무것도 안보여주시는식으로 설계하셨는데
아무것도 없는 데이터를 보여줘도 괜찮은 컴포넌트인가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그게 아니라면 사용처에서 useState로 관리하는게 더 낫지않을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data 가 null 값이어도 컴포넌트 내부 내용의 구조?는 그대로 유지 되기 때문에 아무것도 안보여줘도 괜찮을 것 같다고 생각했습니다! 아니면 데이터가 null 값이었을 때의 추가적인 처리를 선호하시는건가요?
<div> | ||
<SpinLoading /> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
div 태그가 아무런 기능을 하고있는것 같지 않아서 없어도 될거같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수고하셨습니다~
src/api/usersAPI.ts
Outdated
const result = await res.json(); | ||
const { data } = result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구조 분해로 줄일 수 있을 것 같아요
const result = await res.json(); | |
const { data } = result; | |
const { data }= await res.json(); |
useEffect(() => { | ||
const VIEWPORT_HEIGHT = window.innerHeight; | ||
|
||
if (isOpenProfileCard) { | ||
refetch(); | ||
if (positionTop && positionTop > VIEWPORT_HEIGHT / 2) { | ||
setIsAboveProfile(true); | ||
} | ||
} | ||
}, [isOpenProfileCard, userId, refetch, positionTop, isAboveProfile]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구조적으로 봤을 때 의존성 변수가 많은 useEffect 내부에 refetch가 들어가 있습니다.
이는 불필요한 refetch가 발생할 수 있을 것 같아요.
제가 코드를 제대로 이해한 거라면, 저라면 userData를 사용처에서 prop으로 전달하고, 사용자가 마우스를 올렸을 때 데이터를 가져오는 식으로 할 것 같습니다. 아니면 refetch만 따로 다른 useEffect에 분리할 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isAboveProfile을 의존성배열에 넣은 이유가 있을까요?
setState로 값이 변경되면서 한번 더 실행될 것 같은데...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isAboveProfile을 의존성배열에 안 넣으면 hover 할 때마다 프로필의 위치에 따라 유저 카드의 위치를 지속적으로 바꿔줘야하는데 그렇게 안되더라구용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구조적으로 봤을 때 의존성 변수가 많은 useEffect 내부에 refetch가 들어가 있습니다. 이는 불필요한 refetch가 발생할 수 있을 것 같아요. 제가 코드를 제대로 이해한 거라면, 저라면 userData를 사용처에서 prop으로 전달하고, 사용자가 마우스를 올렸을 때 데이터를 가져오는 식으로 할 것 같습니다. 아니면 refetch만 따로 다른 useEffect에 분리할 것 같아요
그렇겠군요,,, 이 부분도 다음 구현 시에도 잘 고려해야겠어요,,!!!
userData를 가져와서 보여주는 것까지가 userDetailCard 컴포넌트의 역할이라고 생각하기 때문에 도원님이 제시해주신 방안 중에서 refetch만 따로 다른 useEffect로 분리하는 방법으로 수정 하겠습니다
<div className={cn('profile-image')}> | ||
<Image src={userInfo?.imgUrl || keydeukProfileImg} alt='프로필 이미지' fill sizes='12rem' /> | ||
</div> | ||
<div className={cn('info-wrapper')}> | ||
<p className={cn('nickname')}>{userInfo?.nickname || '사용자를 찾을 수 없습니다.'}</p> | ||
<p> | ||
<strong>email:</strong> {userInfo?.email} | ||
</p> | ||
<p> | ||
<strong>birthday:</strong> {userInfo?.birth} | ||
</p> | ||
<p> | ||
<strong>phone:</strong> {userInfo?.phone} | ||
</p> | ||
<p> | ||
<strong>gender:</strong> {userInfo?.gender} | ||
</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
userInfo를 못 가져왔을 때는 아예 안 띄우는 식으로 또는 아예 사용자 정보를 찾을 수 없을 때 띄울 컴포넌트를 보여주는 것도 좋을 것 같습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
인스타가 약간 저런 식으로 보여주길래 따라해봤슴니다 ㅎㅎㅎ 아예 안뜨도록 하는 것으로 바꿀가요오?!
width: 45rem; | ||
height: 15rem; | ||
padding: 1rem; | ||
animation: fade-in 1s cubic-bezier(0.39, 0.575, 0.565, 1) both; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
애니메이션 속도 너무 느린 것 같아요.
0.7초에서 0.5초 정도 어떠신가요?
const removeEvent = addEnterKeyEvent({ element: { current: commentRef }, callback: handleSubmitComment }); | ||
return () => { | ||
removeEvent(); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그냥 form으로 만드는 건 별로일까요? 그럼 따로 이벤트 등록 안 해도 될 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
form으로 만들면 엔터키로 제출이 가능하나요? 그래도 따로 이벤트 등록 해야하지 않나요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
라뷰~🫶🏻
<div className={cn('info-wrapper')}> | ||
<p className={cn('nickname')}>{userInfo?.nickname || '사용자를 찾을 수 없습니다.'}</p> | ||
<p> | ||
<strong>email:</strong> {userInfo?.email} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
시멘틱태그 다양하게 쓰는거 좋은데요~
const ApdatedDate = new Date(updateAt); | ||
const timeToString = calculateTimeDifference(ApdatedDate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
호옥시 apdate 오타인가용?
|
||
import classNames from 'classnames/bind'; | ||
import { useState, MouseEvent, useRef, SyntheticEvent } from 'react'; | ||
import Image, { StaticImageData } from 'next/image'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 신기..
interface Position { | ||
left: number; | ||
top: number; | ||
} | ||
|
||
interface ScannerProps { | ||
position: Position; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
먼가 신기해서 내장 타입은 없나 찾아봤는데
type Position = Pick<DOMRect, 'left' | 'top'>;
이렇게 쓸 수 도 있다고 하네용~!~! 참고하셔용
워낙 간단해서 이방법을 쓰면 복잡도가 올라갈 수 도 있다네용! 수정할 필요는 없습니다!!
interface ImageZoomProps { | ||
image: string | StaticImageData; | ||
alt: string; | ||
width: number; | ||
height: number; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interface ImageZoomProps { | |
image: string | StaticImageData; | |
alt: string; | |
width: number; | |
height: number; | |
} | |
interface ImageZoomProps extends ComponentPropsWithoutRef<typeof Image> { | |
width: number; | |
height: number; | |
} |
이거도 그냥 참고만!! 최근에 ComponentPropsWithoutRef
에 대해 배워서 공유 합니당~! 이렇게 하면 이미지의 기본속성타입을 가져올 수 있어용!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오ㅗ오ㅗ옹옹 완젼 꿀팁,,,,
🚀 작업 내용
📝 참고 사항
🖼️ 스크린샷
🚨 관련 이슈 (이슈 번호)
✅ 체크리스트