Skip to content

Conversation

@jungyungee
Copy link

@jungyungee jungyungee commented Oct 25, 2025

배포링크

react-messenger-22nd-jungyungee.vercel.app

이번 과제 관련하여..

이번 과제는 그동안 너무 바쁘고 시간이 부족해서 생각했던 것만큼 완성도 있게 해내지 못했다..
또 중간에 컴퓨터가 한 번 맛이 가서 작업을 하기 어렵기도 했고 그것 때문에 세팅을 다시하느라 너무 많은 시간을 낭비하기도 했다..
급하게 하다보니 코드도 나름 정리해보려고 했지만 뒤죽박죽한 상태이고..
다른 추가적인 기능들도 구현해보려고 하였는데, 필수적인 기능 구현마저도 시간에 쫒겨서 뒤늦게 마무리하게 되었다.. 매우 아쉽다..
시간이 된다면 조금씩 더 수정해보고 싶다

image image image image

구현 기능 - 필수 기능

  • 피그마를 보고 결과화면과 같이 구현 ✅
  • 친구 목록 기능 구현 (친구 목록이 피그마 상 존재하지 않아서 채팅방 내에서 들어갈 수 있는 유저별 프로필 화면을 구현하였음) ✅
  • React Router를 사용하여 친구 목록, 채팅방 목록, 채팅방 등의 페이지를 각각 구성 ✅
  • 페이지를 각각 구성하면서, 각 페이지에서 다른 페이지로 넘어갈 때 데이터를 넘겨주면서 해당 데이터를 가지고 정보를 표시할 수 있도록 함! ✅
  • 로컬스토리지에 채팅방 내용을 저장하여 새로고침 시에도 데이터가 유지 ✅
  • 메세지에 유저 정보(프로필 사진, 이름)를 표시 -> json data로 저장한 정보를 대화창마다 대화상대에 따라 가지고 와서 보여줌 ✅
  • user와 message 데이터를 json 파일에 저장 ✅
  • UI는 반응형을 제외하고 피그마파일을 따라서 진행 ✅

개선 사항 & 신경쓴 부분 & 생각해볼 부분

그래도 기존 과제보다 개선하고자 하였다!

  • 그전에 svg 파일들을 제대로 쓰지 않았어서,, svg 파일로 바꾸어 두었고, 색상 같은 경우 currentColor로 처리해두고 하나로 여러 파일에서 쓰는 등 활용도 있게 쓸 수 있었다
  • 지난번에 user와 message로 data를 정의하고 사용했는데, 이번에는 채팅방 목록부터 유저까지 띄우면서 흐름을 유지해야하다보니, 어떻게 할 것인지 고민해보게 되었다 - 역시 시간이 부족해서 생각한 가장 좋은 방법으로 수정하지는 못했지만,, 의미있는 고민이었다 (필요없는 필드는 만들지 않기,, 앞으로 기능적 확장성을 고려해 넣어야 하는 것들 생각하며 개발하기!)
  • UI를 최대한 깔끔하게 반영해보려고 했다. 기능 자체가 많지는 않지만 좀 보기 좋게 하고자 노력,, (사실 기능적인것보다도 UI를 최대한 반영하고 보기 좋게 만드는데 시간이 걸렸고,,고생했다...)
  • 절대경로로 수정하려고 했는데,, 시간이 없어서 우선 그대로 두었는데 수정할 생각...

Review Questions

  1. React Router의 동적 라우팅(Dynamic Routing)이란 무엇이며, 언제 사용하나요?
    동적 라우팅: URL 경로 일부를 변수처럼 사용하여, 상황에 따라 다른 데이터를 렌더링하는 방식
    예를 들어 이번 과제에서 구현한 것 처럼 /chat/:id에서 :id는 동적 파라미터로, 각 사용자나 채팅방의 고유 ID에 따라 페이지를 다르게 구성할 수 있음!!
    게시글, 프로필, 상품 등 식별자별로 다른 화면을 렌더링해야 할 때 사용한다
    (실제로 과제에서 이를 계속 활용하였음! 대화별 id를 지정하고 그 id로 채팅방을 접근)

  2. 네트워크 속도가 느린 환경에서 사용자 경험을 개선하기 위해 사용할 수 있는 UI/UX 디자인 전략과 기술적 최적화 방법은 무엇인가요?

  • 스켈레톤(Skeleton) UI: 데이터를 기다리는 동안 레이아웃 뼈대를 먼저 보여줘서 사용자에게 ‘로딩 중’이라는 명확한 피드백을 주기
  • 로딩: 로딩중 상태를 보여줄 수 있는 (스피너나 문구) 화면 띄우기
  • 중요한 콘텐츠를 먼저 표시하고, 나머지는 순차적으로 렌더링할 수도 있음

기술 최적화 방법

  • 리소스 최적화: 이미지 포맷 변환이나 코드 등 크기를 줄여서 속도를 빠르게 할 수 있음
  • localStorage 등 이용하면 이전의 데이터를 캐시할 수 있음
  • 데이터 요청 최소화: React Query 같은 라이브러리로 요청을 캐시하고, 중복 API 호출을 방지할 수 있음
  1. React에서 useState와 useReducer를 활용한 지역 상태 관리와 Context API 및 전역 상태 관리 라이브러리의 차이점을 설명하세요.
    useState / useReducer는 컴포넌트 내부의 지역 상태 관리를 하는 것으로
    → 독립적인 UI 단위, 간단한 상태 변화에 효율적임
    Context API / 전역 상태 라이브러리(Redux, Zustand 등)은 여러 컴포넌트가 공유해서 사용할 때 유용한 것으로, 로그인 정보, 테마나 설정 등 웹사이트에서 전역적으로 필요한 데이터들에 활용하는 것이 유용!

Copy link

@dragunshin dragunshin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컴포넌트 분리와 코드 자체도 굉장히 이해하기 쉬워 금방 의미를 파악할 수 있었습니다!
고생하셨습니다!

const el = textRef.current;
setIsOverflowing(el.scrollHeight > el.clientHeight);
}
}, [text]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 isExpanded 도 다시 계산돼야 할 것 같아요

const filters = ["모두", "읽지 않음", "즐겨찾기", "그룹"];

return (
<div className="flex px-4 space-x-2 mt-2 mb-5">

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space-x 를 사용하신 것이 가로 방향으로만 간격이어서 하신 것 같은데
반응형 디자인에는 gap이 더 좋다고 합니다

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


이 링크에서 그 둘의 차이를 설명을 해줍니다 참고하시면 좋을 것 같아요

<button
key={i}
onClick={() => setSelected(i)}
className={`relative flex items-center justify-center px-3 py-1.5 rounded-full border text-[13px] transition cursor-pointer

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 shrink를 사용하면 모바일에서의 문제에 도움이 될 것 같아요

</div>

{/* 필터 버튼 */}
<ChatFilter />

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분에서 모바일 꾸겨짐(?) 이슈가 생기니 확인해보시면 좋을 것 같아요
image

Copy link
Member

@chaeyoungwon chaeyoungwon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

과제하시느라 수고 많으셨어요! 🙌 UI가 너무 예쁘네용
현재 루트가 아닌 경로에서 새로고침 시 404 에러가 발생하는 것 같아요.
vercel.json을 추가하셔서, 지난 3주차 과제 피드백 노션에 안내된 설정을 참고해 적용해보시면 좋을 것 같습니다!
더불어, zustand를 활용해 상태를 관리해보셔도 좋을 거 같아유

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vite 빌드 캐시 파일은 깃에 올라오지 않도록 설정해주시면 좋을 거 같아용

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

svg 네이밍 방식도 통일하면 좋을 거 같아요!
카멜 케이스도 있고 전체가 소문자로 적혀진 파일도 있네용

Comment on lines +6 to +14
<div className="fixed inset-0 flex items-center justify-center bg-gray-100 overflow-hidden">
<div
className="
bg-white shadow-lg overflow-hidden
h-dvh
w-[calc(100dvh*(375/812))]
max-w-[375px]
"
>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 부분은 별도의 레이아웃 컴포넌트로 분리해도 좋을 거 같아용

Comment on lines +94 to +110
{[
{
icon: <CallIcon className="text-white w-6 h-6" />,
label: "오디오",
},
{
icon: <VideoIcon className="text-white w-6 h-6" />,
label: "비디오",
},
{
icon: <SearchIcon className="text-white w-6 h-6" />,
label: "검색",
},
{
icon: <MoreIcon className="text-white w-6 h-6" />,
label: "옵션",
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배열을 별도의 변수로 분리하면, 리턴문이 좀 더 깔끔하고 가독성이 좋아질 것 같아요!

Comment on lines +15 to +20
className={`relative flex items-center justify-center px-3 py-1.5 rounded-full border text-[13px] transition cursor-pointer
${
isSelected
? "bg-gray-150 border-transparent font-semibold text-gray-800"
: "bg-white border-gray-200 text-gray-450"
}`}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조건부 클래스를 사용할 때, clsx나 cn 같은 유틸을 활용해서 좀 더 깔끔하게 관리해도 좋을 거 같아요!!

Comment on lines +7 to +8
"createdAt": "2025-09-26",
"time": "09:15"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

백엔드와 통신할 때는 보통 ISO 형식의 시간 데이터를 받게 되니,
목데이터도 실제 ISO 형태로 넣어두고
이를 원하는 형태로 변환하는 유틸 함수를 하나 만들어두면 좋을 거 같아요!

<button className="w-6 h-6 flex items-center justify-center mr-3">
<PlusIcon />
</button>
<input
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

textarea 태그를 사용해서 여러 줄 입력이 가능하도록 하고, 입력 줄이 늘어날 때 높이도 자동으로 조절되되 지정된 최대 높이까지만 확장되도록 구현해보면 좋을 것 같아요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

실제 마지막 메시지로 보이게 해주셨네용👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unreadcount 또한 읽음 상태를 추가해서 관리해보면 좋을 거 같아용

Comment on lines +84 to +101
{[
{
icon: <CallIcon className="text-main-green w-6 h-6" />,
label: "오디오",
},
{
icon: <VideoIcon className="text-main-green w-6 h-6" />,
label: "비디오",
},
{
icon: <SearchIcon className="text-main-green w-6 h-6" />,
label: "검색",
},
{
icon: <MoreIcon className="text-main-green w-6 h-6" />,
label: "옵션",
},
].map((item, i) => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 분리해주면 좋을 거 같네요!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants