-
Notifications
You must be signed in to change notification settings - Fork 11
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주차] 김지원 미션 제출합니다. #19
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 FriendSearch from "pages/friend/FriendSearch"; | ||
import ChatRoomSearch from "pages/chatroom/ChatRoomSearch"; | ||
|
||
const App: React.FC = () => { |
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.
React.FC를 사용해서 타입 지정 하셨네요! 처음 typescript를 사용할 때 컴포넌트 타입을 어떻게 지정할지 고민이 많았는데 상당히 많은 방법이 있더라구요! 저는 일반적으로 컴포넌트 prop에 타입을 지정하는 편이에요! 찾아보니 FC에 대해 부정적인 생각들이 많더라구요
아래 링크 한 번 읽어보심 좋을 것 같아요~
const GlobalButton: React.FC<GlobalButtonProps> = ({ | ||
customType, | ||
}: GlobalButtonProps): ReactElement => { |
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.
GlobalButton을 정의해서 다양한 용도로 button을 재사용하는 부분 좋은 것 같습니다~~
src/pages/chat/ChatFriendSearch.tsx
Outdated
friend.name.includes(userInput) || | ||
friend.content.includes(userInput) |
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.
채팅방 내용으로도 filtering 하는 부분 좋은 것 같습니다~~
src/pages/chatroom/icon.tsx
Outdated
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 determineShowProfileImage = ( | ||
chat: Array<{ value: string; sender: string; date: string }>, | ||
index: number | ||
) => { | ||
let displayProfile = false; | ||
if (index !== 0) { | ||
const prevSender = chat[index - 1].sender; | ||
if (prevSender !== chat[index].sender) displayProfile = true; | ||
} else displayProfile = true; | ||
return displayProfile; | ||
}; |
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/pages/chatroom/ChatRoom.tsx
Outdated
const randomId = Math.floor(Math.random() * 1000); // 0에서 999 사이의 랜덤 정수 | ||
const created_date = new Date(); | ||
const hours = created_date.getHours(); | ||
const minutes = created_date.getMinutes(); | ||
const daysOfWeek = ["일", "월", "화", "수", "목", "금", "토"]; | ||
const dayOfWeek = daysOfWeek[created_date.getDay()]; | ||
|
||
// 시간을 오전(AM) 또는 오후(PM)로 변환 | ||
const period = hours >= 12 ? "오후" : "오전"; | ||
const formattedHours = String(hours % 12 || 12).padStart(2, "0"); // 0시를 12시로 표시하고 두 자리로 변환 | ||
const formattedMinutes = String(minutes).padStart(2, "0"); // 두 자리로 변환 | ||
const formattedDate = `${created_date.getFullYear()}. ${( | ||
created_date.getMonth() + 1 | ||
) | ||
.toString() | ||
.padStart(2, "0")}. ${created_date | ||
.getDate() | ||
.toString() | ||
.padStart(2, "0")}. ${dayOfWeek}`; | ||
const time = ` ${period} ${formattedHours}:${formattedMinutes}`; | ||
const newItem = { | ||
value: data, | ||
id: randomId, | ||
sender: currentUser.name, | ||
date: time, | ||
calendar: formattedDate, | ||
}; |
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.
추가할 때 formatting 된 형태로 추가하는 것보다 일반 Date형태로 추가한 후, 불러올 때 formatting하는게 사용성이 더 좋을 것 같습니다~ 앱이 확장되어 메시지들간의 sorting이 필요하거나 시간을 기반으로 탐색을 진행하는 등의 기능을 추가하게 된다면 이미 formatting된 시간 정보로는 불가능할 수도 있으니까요!
그리고, formatting하는 기능은 따로 파일을 만들어 정리해두는 것이 재사용성에도 좋을 것 같아요!
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.
이번 주도 고생하셨습니다~! 스타일 시스템이 깔끔하게 잘된 것 같아요!!
export const GlobalStyles = createGlobalStyle` | ||
*::-webkit-scrollbar { | ||
width: 0; | ||
} | ||
body { | ||
background-color: #f6f6f6; | ||
font-family: "Pretendard-Regular"; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
min-height: 100vh; | ||
} | ||
|
||
#root { | ||
background-color: white; | ||
} | ||
`; |
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.
전역으로 스타일 정해서 전체 적용해주신 것 좋은 것 같아요!
<HeaderWrapper> | ||
<GlobalHeader | ||
headText={"채팅"} | ||
leftChild={<GlobalButton customType={"chatsearch"} />} |
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.
Props로 컴포넌트를 통째로 전달할 수도 있군요! 배워갑니다~
.filter((friend, index) => index > 0) // 첫 번째 데이터를 제외 | ||
.filter((friend) => friend.name.includes(userInput)) | ||
.map((filteredFriend, index) => ( | ||
<FriendItem key={index} name={filteredFriend.name} /> | ||
))} |
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.
filter와 map을 이렇게 연속으로 쓸 수도 있네요 ! 저는 보통 필터처리 후 따로 저장하는데 이렇게 처리하는게 더 깔끔한 것 같아요 배워갑니다!
}; | ||
|
||
// InputBox와 SentimentImage를 함께 렌더링하는 useMemo | ||
const inputBoxWithSentiment = useMemo( |
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.
useMemo로 불필요한 렌더링 최소화하는 방식 좋은 것 같아요!
outline: none; | ||
border-radius: 16px; | ||
background-color: ${(props) => | ||
props.isCurrentUser ? "rgba(18, 99, 220, 1)" : "rgba(242, 241, 248, 1)"}; |
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.
style에서 삼항연산자 처리를 할 수도 있네요! 배워갑니다~
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.
json 데이터는 public에서 모아주시는 것도 좋을 것 같아요!
🟪 배포링크
https://react-messenger-18th-phi.vercel.app
🟪 결과화면
🟪 KEY QUESTIONS
1. 디자이너로부터 받은 QA 목록
QA 링크
2. SPA, Routing
전체 페이지를 갱신하는 것이 아니라, 서버로부터 필요한 데이터(업데이트된 부분)만 받아 갱신하면 되기에 사용자와 상호작용이 빠릅니다.
즉, 매번 페이지 전체를 렌더링하지 않아도 되기 때문에 더 나은 사용자 경험을 제공합니다.
3. 상태관리
상태관리란, 변화하는 데이터를 설계된 UI, UX에 맞게 설계하고 구현하고 서버와 주고 받는 데이터를 관리하는 일.
상태관리를 통해 우리는 데이터가 변할 때마다 데이터에 관련된 DOM을 일일히 찾아서 조작하지 않아도 되며 전체 데이터의 형태와 리스트를 한 곳에서 효율적으로 관리할 수 있음.
🟪 Overview
🟪 느낀 점
시험을 3주동안 봐서 빠르게 과제를 시작하지 못한 점이 아쉽습니다🥲 컴포넌트 재사용성을 계속 생각하며 과제 했던 것 같습니다.
앗 그리고 디자이너 분이 요청 드리면 빠르게 반영해주셔서 정말 감사했습니다!!
나중에 좋아요 표시 등의 추가적인 기능을 구현해보고자 합니다~
다들 수고 많으셨습니당!!