-
Notifications
You must be signed in to change notification settings - Fork 10
[4주차] 백승선 과제 제출합니다 #19
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
base: main
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.
안녕하세요, 승선 님! 이번주차 과제도 수고 많으셨습니다 👍👍 현재 node_modules 파일이 PR에 함께 올라와 있어서 파일을 확인하기 어려운 상황이니 다시 한번 확인해 주세요! 코드리뷰는 일단 남겨 놓았습니당
| <nav className="flex justify-between mt-[10px] text-[11px] font-pretendard leading-[1.4] z-10 bg-white"> | ||
| <Link to="/"> | ||
| <div className={"ml-[32px]"}> | ||
| <img src={(current === "/" ? friendsTabOn : friendsTab)} alt={friendsTab} /> |
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.
전체적으로 svg 파일을 img로 불러와서 쓰고 계신데, svg를 컴포넌트화 하면 상태에 따라 UI 변화를 tailwind로 대응하기 더 쉬울 것 같습니다!
| import navbarT from "@/assets/chatList/navbarT.svg" | ||
| import dots from "@/assets/chatList/dots.svg" | ||
|
|
||
| export default function NavBar() { |
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.
반복해서 같은 요소를 여러 개 사용하고 있으니, 네비게이션 아이템을 객체로 정리 + map 으로 렌더링하면 좋을 것 같네요!
| </div> | ||
| <img src={Profile} className={"w-[26px] h-[26px] ml-[5px] cursor-pointer"} alt="profile" /> | ||
| <span className={"ml-[12px] cursor-pointer text-[16px] leading-[1.4] font-semibold"}> | ||
| {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.
mock data에서는 문제가 될 만큼 길어지는 이름이 없는 것 같긴 하지만, 사람이 늘어나서 이름이 길어질 때를 대비해 둘 필요가 있을 것 같네요!
| </Link> | ||
| </div> | ||
| <img src={Profile} className={"w-[26px] h-[26px] ml-[5px] cursor-pointer"} alt="profile" /> | ||
| <span className={"ml-[12px] cursor-pointer text-[16px] leading-[1.4] font-semibold"}> |
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 css를 사용하고 계시니, typography를 미리 정의해 두시면 매번 크기를 직접 넣을 필요가 없어 tailwind의 장점을 더 살릴 수 있을 것 같습니당
|
|
||
| //입력창에 입력할 시 | ||
| const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => { | ||
| if (e.key === "Enter" && !e.shiftKey && !composing) { |
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 Keyboard Event에는 이미 정의된 e.nativeEvent.isComposing 이 존재하니 이를 활용하시면 state를 활용할 필요 없이 코드가 간결해질 것 같아요!
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.
알려주셔서 감사합니다!
| {/*프로필 사진*/} | ||
| {profileSrc && ( | ||
| <img | ||
| src={profile} |
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.
profileSrc를 Props로 받고 있는데 이 부분은 default 값을 사용하는 이유가 있을까요?
| <div className="flex w-full bg-white px-4 py-3 items-center justify-center"> | ||
| {/*profile pic avatar*/} | ||
| <div className="mr-[7px] flex items-center justify-center"> | ||
| <Link to={`/chat/${chat.id}`}> |
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.
Profile 이미지에만 link를 걸어두신 이유가 있을까요?? chatListItem 컴포넌트 전체에 link를 걸어두는 게 사용자 입장에서 더 자연스러운 흐름일 것 같아요!
|
|
||
| const ChatListItem: React.FC<ChatListItemProps> = ({ chat }) => { | ||
| let preview = getPreviewText(chat); | ||
| let lastSent = "어제"; |
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.
현재 chatlist 화면에서 확인 가능한 메시지 전송 날짜가 어제로 하드코딩 되어 있는 것 같은데 맞을까요? 마지막 메시지 실제 시간 반영이 필요해 보입니다!
| import NavBar from "@/components/NavBar"; | ||
| import React from "react"; | ||
|
|
||
| export default function HomeBody() { |
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.
현재 node_modules 파일 때문에 사진 업로드가 안 되는 오류가 있는 것 같은데, 이 컴포넌트에서 드롭다운을 접으면 아래 네비바가 함께 딸려올라옵니다!
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> | ||
| <SalesFriends /> | ||
| <div className = "flex flex-col mt-auto z-20"> | ||
| <NavBar /> |
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.
NavBar 컴포넌트가 고정된게 아니라 HomeBody안에 있어서 친구 목록을 숨기기를 하면 NavBar도 함께 위로 올라가고 있습니다 NavBar를 이 부분에 포함하면 안될 거 같습니다..!!
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.
public/profile 폴더에 똑같은 사진들이 있어요..!!
Wannys26
left a comment
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.
dateCalculation.tsx => dateCalculation.ts로 파일 확장자 변경하시면 좋을 거 같습니다!
| : `${Date.now()}_${Math.random()}`; | ||
| } | ||
|
|
||
| const time = new Date().toLocaleTimeString("ko-KR", { |
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.
이 time 변수는 웹 페이자가 처음 실행될 때 딱 한 번만 실행이 되는거 같습니다!
여기서 2:13분에 사이트가 켜졌다면, 앞으로 보내는 모든 메시지가 " 2:13분"으로 찍히게 되는거 같습니다.
| senderName: params.senderName, | ||
| senderId: params.senderId, | ||
| text: params.text, | ||
| sentAt: time, |
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.
여기서도 고정된 시간 변수 time을 받고 있습니다! time 변수를 삭제하고
위의 Message 타입을 정의할 때, sentAt의 타입을 Date로 수정하시고 가져다 쓰시는게 좋을 거 같습니다!
| senderName: "나", // or whatever your display name is | ||
| senderId: "000", // you = "000" in your model | ||
| text, | ||
| sentAt: "어제", // you can pretty-format current time here |
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.
여기 "어제"라고 sentAt이 고정되어있습니다!
const currentTime = new Date().toLocaleTimeString("ko-KR", {
hour: "numeric",
minute: "2-digit",
});
이런 식으로 currentTime이라는 변수를 만들고,
sentAt: currentTime 이렇게 수정하시면 현재 시간을 가져다 쓰실 수 있을 거 같습니다!
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.
덧붙혀 chatListUtils.ts도 한번 확인해보시면 좋을 거 같습니다
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="mr-[7px] flex items-center justify-center"> | ||
| <Link to={`/chat/${chat.id}`}> | ||
| <img src={`/profile/${chat.avatar}.svg`} alt={chat.name} /> | ||
| </Link> |
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.
채팅방 목록에서 프로필 이미지 부분만 채팅방 안에 들어갈 수 있도록 되어있습니다..! 링크 될 수 있는 범위를 넓히는게 더 UX측면에서 더 좋을거같습니다...!!
| senderName={m.senderName} // can be undefined | ||
| profileSrc={`/avatars/${m.senderId}.svg`} // avatar per senderId | ||
| /> | ||
| ))} |
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.
메시지를 보내면 화면 하단으로 이동하도록 수정하면 UX가 더 향상 될 거 같습니다!
| onSend={handleSend} | ||
| onImageSend={() => {}} | ||
| onEmoji={() => {}} | ||
| onAdd={() => {}} |
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.
현재 새로고침하면 404오류가 뜹니다 이 파일에
{
"rewrites": [
{ "source": "/(.*)", "destination": "/" }
]
}
이 코드를 추가하면
모든 요청을 index.html로 리다이렉트합니다.
이 방식으로 해결할 수 있을 거 같습니다..!!
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.
두명의 참여자가 합쳐진 아이콘을 사용하기보다 채팅방 더미데이터에서 채팅방에 들어있는 참여자를 불러오고 그 참여자의 프로필을 불러오는 방식이 더 좋아보입니다..!
https://react-messenger-22nd-bunxwiyhx-baekseungsuns-projects.vercel.app
구현 화면 캡쳐
느낀점
###Review Questions
1. React Router의 동적 라우팅(Dynamic Routing)이ㄴㅇㄹㄴ란 무엇이며, 언제 사용하나요?
React Router의 동적 라우팅이란 라우트를 코드 실행에 따라 동적으로 생성하는 방식이다.
/user/:userId 를 예시로 들 수 있다. 같은 컴포넌트를 재사용하면서도 URL에 따라UI나 데이터를 다르게 보여줄 수 있다는 장점이 있다.
2. 네트워크 속도가 느린 환경에서 사용자 경험을 개선하기 위해 사용할 수 있는 UI/UX 디자인 전략과 기술적 최적화 방법은 무엇인가요?
** React에서 useState와 useReducer를 활용한 지역 상태 관리와 Context API 및 전역 상태 관리 라이브러리의 차이점을 설명하세요**
useState와 useReducer는 컴포넌트 내부에서만 작동하는 지역 상태 관리 방식으로, 구현이 간단하고 불필요한 리렌더링이 적어 성능상 효율적이다. 또한 작은 규모의 상태를 다루기엔 직관적이고 효율적이다. 그러나 여러 컴포넌트가 같은 상태를 공유해야 할 경우 props를 통해 전달해야 하므로 구조가 복잡해지고 유지보수가 어려워진다는 단점이 있다.
Context API나 전역 상태 관리 라이브러리는 하나의 전역 저장소를 통해 여러 컴포넌트가 동일한 상태를 쉽게 공유할 수 있다. 따라서 로그인 정보, 테마, 사용자 설정 등 전역적으로 필요한 데이터를 관리하기에 용이하다. 그렇지만 전역 상태가 변경될 때 관련된 모든 컴포넌트가 함께 리렌더링될 수 있어 성능 저하가 발생할 수 있으며 설정이 복잡하다. 떄에 따라선 여러 전역상태 관리가 사용되면 코드가 복잡해지기도 한다. 결과적으로 useState와 useReducer는 단순하고 빠르지만 범위가 제한되고, Context API 및 전역 상태 관리 라이브러리는 유연한 공유가 가능하지만 관리 비용이 크다는 차이가 있다.