-
Notifications
You must be signed in to change notification settings - Fork 10
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
[4주차] 이가빈 과제 제출합니다. #13
base: master
Are you sure you want to change the base?
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.
과제 너무 고생하셨습니다!!❤️🔥❤️🔥❤️🔥
import profileIcon from "../../assets/ChatRoom/profile.svg"; | ||
import { UserData } from '../../lib/UserData'; | ||
import { formatTimeForChatList } from '../../utils/ClockUtils'; |
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.
가빈님도 절대경로를 설정해보는건 어떨까용?! import가 훨씬 쉬워질거에요!
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.
다른 파일들과 함께 보니 전반적으로 따옴표와 쌍따옴표를 혼용하고 계신 것 같아요. 이런 부분은 Prettier를 쓰면 쉽게 통일할 수 있습니다!
return ( | ||
<div | ||
className="w-full h-chatBarHeight bg-White flex items-center pl-[16px]" | ||
style={{ boxShadow: "0px -4px 8px 0px rgba(0, 0, 0, 0.08)" }} |
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.
앗 이부분은 tailwind로 처리하지 않으신 이유가 있을까요?
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.
이렇게 indent depth가 깊어지면 나중에 원하는 부분을 찾기 어려워질 것 같아요. 컴포넌트로 분리할 수 있는 부분은 분리해보는게 어떨까요?
if (!currentUser) return; | ||
|
||
// chatKey 생성 | ||
const chatKey = `${Math.min(currentUser.userId, userId)}_${Math.max(currentUser.userId, userId)}`; |
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.
오 key를 생성하는 방식이 특이하네요!👍
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.
헉 펑까지 구현하셨네요😂😂😂
// 각 유저별 메시지 불러오기 | ||
if (currentUser && user.userId !== currentUser.userId) { | ||
// currentUser와 user 간의 공통 대화 키 생성 | ||
const chatKey = `messages_${Math.min(currentUser.userId, user.userId)}_${Math.max(currentUser.userId, user.userId)}`; |
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.
key를 구하는 함수는 따로 빼서 재사용해도 될 것 같아요!
<Line /> | ||
<Birthday /> | ||
<Line /> | ||
<FriendList /> |
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.
컴포넌트를 나눠서 깔끔하고 좋네용ㅎㅎ👍
if (diffInDays === 0) { | ||
return timeString; | ||
} else if (diffInDays === 1) { | ||
return `(어제) ${timeString}`; | ||
} else if (diffInDays === 2) { | ||
return `(그저께) ${timeString}`; | ||
} else if (diffInDays <= 3) { | ||
return `(${diffInDays}일 전) ${timeString}`; | ||
} else { | ||
const month = date.getMonth() + 1; | ||
const day = date.getDate(); | ||
return `(${month}/${day}) ${timeString}`; | ||
} |
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.
자세한 분기 처리 좋아용👍👍
그런데 if문 안에 return이 있기 때문에 뒤에서는 else if가 아니라 그냥 If로, else는 없애도 된답니다!
이 부분도 함수로 따로 빼서 재사용하셔도 좋을 것 같아요~
type="text" | ||
value={message} | ||
onChange={(e) => setMessage(e.target.value)} | ||
onKeyDown={handleKeyDown} |
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.
사진처럼 onKeyDown 썼을 때 한글 마지막이 두번 입력 되는데 한번 읽어보세요
{/* 상대방 메시지 렌더링 */} | ||
{!isCurrentUser && ( |
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.
저도 여러명이랑 채팅하는 기능을 구현하는데 시간을 많이 쏟았던 것 같아요ㅠㅠ
그래도 이번 과제도 잘 해내셨군요 수고하셨어요 ㅎㅎ
근데 제 노트북에서는 스크롤을 해야 전체 화면을 확인할 수가 있어서 그 부분만 조금 수정해주시면 전체적으로 보기 더 좋을것 같습니다!
interface LastMessage { | ||
text: string; | ||
timestamp: Date; | ||
} |
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 lastMessage = messages[messages.length - 1];
이렇게 메시지 배열이 있다면, 마지막 요소르 가져오는 식으로 하면 될 것 같습니다.
const handleBackClick = () => { | ||
navigate('/chatlist'); | ||
} |
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.
이렇게 따로 네비게이션 관련 함수를 만들어서 주소 이동을 하도록 해주셨네요!
이 방법말고도 를 활용하는 방법도 있더라구요.
이 방법을 쓰면 굳이 주소 이동을 위한 함수를 작성하지 않아도 되어서 저는 덜 번거로웠던 것 같아요
useNavigate
도 많이 활용한다고 하는데 찾아보니 로그인하지 않은 사용자가 프로필 페이지에 접근하려고 하면, 로그인 페이지로 리디렉션 하는 경우에 주로 쓴다고 하더라구요. 저도 이번 키question공부하면서 알게되었습니다 ㅎㅎ
const getIconStyle = (path: string) => { | ||
return activePath === path ? "#AB78FF" : "#666666"; | ||
} |
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.
글씨 색을 경로와 일치하는지에 따라 다르게 두셨네요!
약간 하드코딩느낌이 있어서 boolean값을 활용한다면 좀 더 깔끔하게 구현할 수 있을 것 같습니다.
const hours = date.getHours(); | ||
const minutes = date.getMinutes(); | ||
const ampm = hours >= 12 ? '오후' : '오전'; | ||
const formattedHours = hours % 12 === 0 ? 12 : hours % 12; |
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 hours = date.getHours(); | |
const minutes = date.getMinutes(); | |
const ampm = hours >= 12 ? '오후' : '오전'; | |
const formattedHours = hours % 12 === 0 ? 12 : hours % 12; | |
const formattedTime = new Date().toLocaleTimeString('ko-KR', { | |
hour: '2-digit', | |
minute: '2-digit', | |
}), | |
배우고 느낀 점
많은 시간을 투자한 부분
chat/:userId
로 설정했더니 사용자가 전환되었을 때 메시지가 렌더링되지 않거나 섞이는 등의 오류가 있어서 이를chatKey
를 부여하는 방식으로 해결하는데 시간이 오래 걸렸습니다.구현 기능
배포 링크
https://react-messenger-20th-sable.vercel.app/
Key Question
1. React Router의 동적 라우팅(Dynamic Routing)이란 무엇이며, 언제 사용하나요?
✅정적 라우팅
✅동적 라우팅
:
기호를 사용하여path/:문자열
의 형태로 표현한다.경로/
뒤에 무슨 문자열이 오든 해당 Route로 연결된다.chatKey
와 같은 문자열을 path parameter라고 한다.2. 네트워크 속도가 느린 환경에서 사용자 경험을 개선하기 위해 사용할 수 있는 UI/UX 디자인 전략과 기술적 최적화 방법은 무엇인가요?
✅UI/UX 디자인 전략
✅기술적 최적화 방법
3. React에서 useState와 useReducer를 활용한 지역 상태 관리와 Context API 및 전역 상태 관리 라이브러리의 차이점을 설명하세요.
✅지역 상태
useState
useReducer
useState
와 달리 다양한 액션에 따라 다양한 상태 변화를 관리하기 용이하다.✅전역 상태 관리
Context API
React.createContext()
를 통해 상태를 전역으로 관리할 수 있다.Provider
를 통해 데이터를 하위 컴포넌트에 전달하며,useContext
훅을 통해 데이터에 접근한다.Context
로 관리해야 할 경우 구조가 복잡해질 수 있다.전역 상태 관리 라이브러리