Skip to content

[4주차] 권동욱 미션 제출합니다. #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

Open
wants to merge 119 commits into
base: master
Choose a base branch
from

Conversation

2025314242
Copy link

@2025314242 2025314242 commented Apr 16, 2025

마치며...

Todo list

  • 전역 상태 관리를 위해 react의 createContext, ContextProvider를 사용하였다. 추후 진행될 과제/프로젝트 등에서는 redux 라이브러리 공부를 해서 사용해보고자 한다.
  • 해당 과제에서 라이브러리는 가능한 적게 사용하려고 하였는데, 한글 검색 (초성, 중성, 종성 포함) 의 경우 로직이 너무 복잡하다고 생각되어 부득이하게 hangul-js 라이브러리를 사용하였다.
  • 안 읽은 메시지의 경우 로그인/회원가입 기능이 따로 구현되어 있지 않아 데이터 (local storage) 내에는 속성/값이 존재하지만 실제로 표시하지는 않았다. 추후 백엔드 파트와 협업 혹은 프로젝트를 진행하게 되는 경우 추가하고자 한다.

Error handling

모바일 상에서 웹 브라우저를 통해 접속하는 경우 컴퓨터 상에서 표시되는 것과 차이가 있어 수정하는 과정에서 애를 먹었다. 구체적으로

Case 1
❌ textarea 태그가 화면 밖으로 삐져 나왔다.
✅ width: 100%;

Case 2
❌ 모바일 화면이 작은 경우 레이아웃이 붕괴되었다.
✅ width: 100%; height: 100vh; max-width: 375px; max-height: 812px;

Case 3
❌ 디자인 상 input 태그에 입력되는 텍스트 크기가 14px인 경우 (< 16px) 자동 줌인이 발생하였다.
✅ font-size: 16px; transform: scale(0.875); transform-origin: left center;

등이 있다.

배포 링크

https://react-messenger-21th-kwondu.vercel.app/

Key Questions

React Router의 동적 라우팅(Dynamic Routing)이란 무엇이며, 언제 사용하나요?

동적 라우팅은 URL 경로의 일부를 변수처럼 다루어, 라우트 정의 시점에 정해지지 않은 여러 경로에 대응할 수 있도록 하는 방식이다.

...
<Routes>
  <Route path="/users/:userId" element={<UserDetail />} />
</Routes>
...

상단 코드와 같이 설정한 경우 /users/123로 접근했을 때 UserDetail 컴포넌트가 렌더링되며, useParams() 훅으로 userId 값을 가져올 수 있다.

import { useParams } from 'react-router-dom';
...
function UserDetail() {
  const { userId } = useParams(); 
  console.log(userId); // 123
}
...

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

UI/UX 디자인 전략

Skeleton UI나 로딩 바, lazy loading(사용자가 필요한 시점에만 특정 리소스 로드) 등을 통해 개선할 수 있다.

기술적 최적화 방법

데이터 압축, 브라우저 caching, lazy loading 등을 통해 개선할 수 있다.

React에서 useState와 useReducer를 활용한 지역 상태 관리와 Context API 및 전역 상태 관리 라이브러리의 차이점을 설명하세요.

지역 상태는 단일 컴포넌트 혹은 컴포넌트 트리의 일부에서 주로 사용된다.

  • 장점: 구현이 쉽고, 불필요한 리렌더링을 피할 수 있다.
  • 단점: 여러 컴포넌트에서 동일한 상태를 사용해야 하는 경우 props drilling (특정 상태를 하위 컴포넌트로 전달하기 위해 중간 컴포넌트를 통해 property를 내려주는 것) 이 발생할 수 있다.

전역 상태는 어플리케이션 전반에 공유해야 하는 데이터에 주로 사용된다.

  • 장점: 여러 컴포넌트 간 상태 공유가 용이하며, 로직 모듈화에 유리하다.
  • 단점: 러닝 커브와 Boiler Plate 코드 (별 수정 없이 반복적으로 사용되는 코드) 가 존재한다.

initialize setting, file structure, and css reset (mayer's reset)
Pretendard, using styled-components
icons for navigation bar (home, chat, call, plus)
tailwind css
typography, color, phone grid
home, chat(list, room), home, plus
use Outlet (react router)
add indicator (black/white) to navigation bar
modify folder structrue of view components
set background color to black
display phone grid at center
add indicator, seperate with navigation bar
add status bar (with celluar, wifi, battery icons)
modify letter spacing + -> -
add new font status bar
add custom hook colok (HH:MM)
grayscale-00-black
using crypto
save initial chat data to local storage if and only if there are no
local storage data
Copy link

@only1Ksy only1Ksy left a comment

Choose a reason for hiding this comment

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

4주차 과제 하시느라 고생 많으셨습니다!!

@@ -0,0 +1 @@
"user-me"

Choose a reason for hiding this comment

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

이렇게 하면 따로 꺼내쓸 때 편리하겠네요!! 저는 한 파일에 저장해 놓았어서 나중에 꺼내 쓰기가 번거로웠는데 배워갑니다!

Choose a reason for hiding this comment

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

지워도 되는 파일 같습니다!

position: absolute;
top: var(--statusbar-height);
width: 100%;
heigth: 46px;

Choose a reason for hiding this comment

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

Suggested change
heigth: 46px;
height: 46px;

{filteredNormalChats.length > 0 && (
<S.ChatGroup className={`${isNormalGroupTop ? 'top-group' : ''}`}>
{sortChatsByLastMessage(filteredNormalChats).map(([chatId, room]) => (
<ChatItem key={chatId} chatId={chatId} userList={userList} myId={myId} room={room} isPinned={false} />

Choose a reason for hiding this comment

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

핀 설정은 채팅창 내부에서만 할 수 있는 게 맞을까요?? 채팅 리스트 창에서는 해제만 가능한 것으로 보여서요!

Copy link
Author

Choose a reason for hiding this comment

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

넹 디자인 상에서는 해당 플로우만 짜여져 있어서 이렇게 설정했습니다!

import * as S from './ChatItem.Styled';
import * as Types from '@/types';
import * as Icons from '@/assets/icons/chatlist';
import { CHATCOLOR_ITEMS } from '@/constants/chatcolor';

Choose a reason for hiding this comment

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

상수로 관리하니까 확실히 코드가 깔끔해지고 좋은 것 같아요!

/>
);
} else {
const colorItems = CHATCOLOR_ITEMS[memberIds.length] || CHATCOLOR_ITEMS[4];

Choose a reason for hiding this comment

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

보면 유저 원래 프로필과는 상관없이 인원수에 맞게 색만 다르게 해서 보여주는 방식인 것 같은데 맞을까요?? 그렇게 설정하신 이유가 따로 있는지도 궁금합니다!

Copy link
Author

Choose a reason for hiding this comment

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

유저 프로필 별로 적용해서 하는 게 당연히 제일 좋은데, 제가 귀찮아서 커스텀 프로필 이미지 설정을 안 했다보니 그냥 이렇게 했습니다.. 추후 개발 과정에서 적용하는 게 더 좋을 거 같네요 !

Choose a reason for hiding this comment

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

저는 아직 어떤 함수를 util로 뺴야 할지에 대한 기준이 모호해서 혹시 어떤 기준으로 관리하시는지 궁금합니다!

Copy link
Author

Choose a reason for hiding this comment

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

저는 기본적으로
여러 컴포넌트에서 사용된다 -> utils 폴더로 분리
특정 컴포넌트에서 사용되고, state 변경이 직접적으로 일어나지 않는 선까지 -> utils.ts 파일로 분리
이렇게 사용하는 거 같습니다

@@ -0,0 +1,129 @@
/* http://meyerweb.com/eric/tools/css/reset/

Choose a reason for hiding this comment

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

코드리뷰 남겨주신 거 확인했는데 저도 다음에 적용해봐야겠네요!!

return (
<S.ChatItemWrapper key={chatId}>
{ChatPreviewImage(chatId, memberIds, userList)}
<Link to={`/chat/${chatId}`} className={`chat-link`}>

Choose a reason for hiding this comment

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

이런 식으로 활용할 수 있군용 이것도 코드리뷰에 남겨주신 것 확인했는데 참고하겠습니다!!

- typing error
- empty file
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.

2 participants