Skip to content
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주차] 강다혜 미션 제출합니다. #20

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

Conversation

psst54
Copy link

@psst54 psst54 commented Nov 3, 2024

3 & 4주차 미션: React-Messenger

🌊 결과물

배포 링크 :
https://react-messenger-20th.vercel.app/chat

기능 구현

/chat 페이지

  • 대화를 클릭해 해당 대화 페이지로 이동할 수 있다.

/chat/{id} 페이지

  • 하단 입력창에서 메시지를 입력하고, 엔터 혹은 오른쪽 파란 전송 버튼을 통해 메시지 전송이 가능하다.
    • Shift + enter를 통해 빈 줄을 추가할 수 있다.
  • 상단 navbar 프로필 사진 및 이름을 클릭하면 상대방<->나 유저 전환이 가능하다.
  • 더블클릭을 통해 상대방의 메시지에 리액션을 보낼 수 있다.

🌊 Key Questions - 4주차

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

  • 동적 라우팅은 웹에서 URL 경로에 따라 다른 컴포넌트를 동적으로 렌더링하는 방식이다.
  • React에서는 React Router 라이브러릴르 추가해 동적 라우팅을 간편하게 사용할 수 있다.

예시

  • 사용자의 개별 페이지
    • /profile/:id처럼 사용해 id에 따라 각각 다른 사용자의 정보를 보여줄 수 있다.
  • 검색 결과 페이지
    • /search/:query 경로를 이용하면 query에 따라 검색 결과를 보여줄 수 있다.

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

이미지 최적화

  • 이미지를 압축하거나, 크기를 조절해 이미지의 용량을 줄인다.
  • 웹에서는 webp 확장자를 주로 사용한다.

code splitting

  • 코드를 여러 개의 번들로 나누어 필요한 부분만 로드한다.
  • 초기 로딩 시에도 모든 코드를 한 번에 불러오지 않고, 각 페이지별로 필요한 코드만 필요시에 로드한다.
  • 불필요한 코드나 라이브러리는 로드하지 않는다.

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

useState

  • 가장 기본적으로 사용되는 상태 관리 hook이다.
  • 코드가 간결하고 직관적이다.
  • 상태 변경 로직이 복잡한 경우, 코드 가독성을 해칠 수 있다.

useReducer

  • 상태와 상태 변경 로직을 분리해서 관리한다.
  • 복잡한 상태 로직을 reducer 함수로 깔끔하게 관리할 수 있다.

 

  • useState나 useReducer는 하나의 컴포넌트 또는 컴포넌트의 트리에서 지역적으로 상태를 관리할 사용한다. 여러 컴포넌트에 걸쳐 관리되는 상태의 경우에는 props drilling 문제가 발생할 수 있으므로 다른 방법을 사용할 수 있다.

context API 및. 전역 상태 관리 라이브러리

  • 상태를 상위 컴포넌트에서 전달하지 않고도 하위 컴포넌트에서 접근할 수 있다.
  • 예시) 테마, 시간대, 다국어 설정 등 여러 컴포넌트에서 공통적으로 사용되는 상태

🌊 Key Questions - 3주차

디자이너로부터 전달받은 피그마 링크, 피그마 캡처본, 디자이너와의 소통 tmi 등

  • 피그마 링크
  • 캡처본
  • 소통 TMI
    • 디자이너님과 소통하면서 플젝을 하는게 꽤 오랜만이네용ㅎㅎㅎ,, 주어진 디자인을 잘 구현하는 것도 FE 개발자에게 중요한 역량이라고 생각하기 때문에 최대한 노력했는데 잘 됐는지 모르겠어요...!
    • 중간에 제가 "채팅 메시지 최대 길이 정해주면 좋을 것 같아요!"라고 말씀을 드렸는데, 알고 보니 피그마에 지정을 해 놓으셨더라구요! 정신 바짝 차리겠습니당,,🫠🫠
    • 사실 저는 css에서 단위를 px, pt보다는 rem을 선호하는 편이라 보통 root font size 16px에 0.25rem / 0.5rem / 0.75rem / 1rem 간격으로 사이즈를 조절했었는데요...! 이번 디자이너님은 5px, 6px, 7px, 8px,.... 25px 등 단위를 다양하게 사용하셔서 어떻게 구현할 지 고민이 됐었어요. 하필 이번에 tailwind를 써보자고 마음을 먹었는데 tailwind와 px 단위 디자인은 궁합이 잘 안 맞는 것 같더라고요...ㅎㅎ 만약 실제 플젝이었으면 디자인을 수정해주실 수 있는지 말씀드리거나 제가 기술 스택을 바꿨을텐데, 이번에는 간단한 과제이다보니 그냥 tailwind도 쓰면서 디자이너님의 디자인을 정말 충실히 구현해보자! 하는 기분으로 코딩했어요🥰🥰

JSX, JS, TSX, TS 각각의 확장자 개념 사용이유와 차이점.

JS

  • JS는 프로그래밍 언어로, 웹 페이지를 만드는 데에 많이 사용된다. 꼭 웹 페이지에 한정된 것은 아니고, 비 브라우저 환경에서도 작동한다.
  • 프로토타입 기만, 단일 스레드, 동적 언어로, 객체지향형, 명령형, 선언형 스타일을 지원한다.
  • 웹 페이지에서는 보통 동적인 웹을 구축하는 역할을 맡는다.

JSX

  • JSX는 JS의 구문을 확장한 것으로, JS 파일 안에 HTML과 유사한 마크업을 작성할 수 있게 한 것이다.

  • 기존에는 콘텐츠를 HTML, 디자인을 CSS, 로직을 JS 파일에 작성했다. 하지만 JSX를 이용하면 마크업과 렌더링 로직을 같은 파일에 작성할 수 있다!

  • JSX element는 syntactic sugar로, JSX 코드는 JS 코드로 변환될 수 있다.

    • 따라서 아래와 같은 JSX 코드는

      class Hello extends React.Component {
        render() {
          return <div>Hello {this.props.toWhat}</div>;
        }
      }
      
      const root = ReactDOM.createRoot(document.getElementById('root'));
      root.render(<Hello toWhat="World" />);
    • 이렇게 컴파일된다!

      class Hello extends React.Component {
        render() {
          return React.createElement('div', null, `Hello ${this.props.toWhat}`);
        }
      }
      
      const root = ReactDOM.createRoot(document.getElementById('root'));
      root.render(React.createElement(Hello, { toWhat: 'World' }, null));

TS

  • TypeScript는 JavaScript의 super set 프로그래밍 언어로, JS 코드로 변환될 수 있다.

TSX

  • TypeScript + JSX라고 이해하면 된다. JSX 문법과 TS의 타입 시스템을 동시에 사용할 수 있다.

TypeScript를 사용하는 이유.

  • JS로 만드는 프로그램의 규모가 점점 커지고, 방대한 코드를 타입 없이 작성하려니 타입 관련 오류와 오타가 많이 발생하게 되었다. TS는 타입 관련 오류와 오타를, 코드를 실행하기 전에 잡아주므로 실제로 코드를 실행했을 때 오류가 나는 경우가 많이 줄어들게 된다.

SSR과 CSR 특성 및 차이점.

SSR(Server-Side Rendering)과 CSR(Client-Side Rendering)은 웹을 렌더링하는 두 방식이다.

SSR(Server-Side Rendering)

  • SSR은 화면의 렌더링이 서버에서 이루어지는 아키텍쳐이다.
  • 첫 HTML 렌더링을 서버에서 처리하기 때문에, 사용자의 화면에 컨텐츠가 그려지는 데 걸리는 시간이 더 짧다.
  • 별도의 서버가 필요 없는 CSR과는 달리 서버가 필요하다.
    -SSR은 요청에서 필요한 정보를 파악하고, 적절한 페이지 파일을 가져와 렌더링을 처리한 후, 완성된 HTML과 JS 번들을 돌려주어야 한다.

CSR(Client-Side Rendering)

  • CSR은 렌더링 프로세스가 클라이언트 측(일반적으로 사용자의 웹 브라우저)에서 발생하는 기술이다.
  • 클라이언트가 서버에 추가 요청을 하지 않고도 UI를 업데이트할 수 있다. 따라서 부드럽고 반응이 빠른 사용자 경험을 제공한다.

참고

Copy link

@billy0904 billy0904 left a comment

Choose a reason for hiding this comment

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

다혜님 과제를 테스트해보면서 UI가 피그마랑 똑같이 정말 잘 구현되어있다는 생각을 했습니다 ㅎㅎ 항상 느끼는 거지만 코드도 깔끔하고 좋네요!! 👍🌟

4주차 과제도 정말 수고 많으셨습니다! 🍀

Comment on lines +1 to +2
import CameraIcon from '@assets/CameraIcon';
import SearchIcon from '@assets/SearchIcon';

Choose a reason for hiding this comment

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

확실히 절대경로로 import하는게 라인 길이도 줄어들고 훨씬 깔끔하네요! 👍👍 저도 다음 과제에서는 절대경로를 사용해봐야겠습니다!

Comment on lines +28 to +30
const myMessageStyle = `bg-blue text-white rounded-r-message-sm
${isFirst ? 'rounded-tr-message-lg' : ''}
${isLast ? 'rounded-br-message-lg' : ''}`;

Choose a reason for hiding this comment

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

동적 스타일을 상수로 빼서 선언해주신 점 너무 좋은 것 같습니다! 👍

Comment on lines +7 to +24
const router = createBrowserRouter([
{
path: '/',
element: <MainPage />,
},
{
path: '/chat/:id',
element: <ChatPage />,
},
{
path: '/follower',
element: <FollowerPage />,
},
{
path: '/chat',
element: <ChatListPage />,
},
]);

Choose a reason for hiding this comment

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

저는 모든 라우팅을 <Route> 태그로 감싸는 방식으로 코드를 작성했는데 이렇게 상수처럼 사용하는 방식도 있네요! 다혜 님 코드를 볼 때마다 항상 변수 사용을 잘 하신다는 생각이 듭니다 ㅎㅎ 간결하고 너무 좋아요!

Comment on lines +6 to +39
export default function NavBar({ otherUser }: { otherUser: User }) {
return (
<nav
className="flex items-center justify-between
w-full h-16 px-4
border-b border-colors-blue_gray"
>
<div className="flex items-center gap-15px">
<BackIcon size="24px" />

<div className="flex gap-10px">
<button type="button">
<img
src={otherUser.profileImgUrl}
alt="user profile"
className="w-icon h-icon rounded-full"
/>
</button>
<div className="flex-col">
<button type="button">
<p className="body1">{otherUser.name}</p>
</button>
<p className="body5">{otherUser.id}</p>
</div>
</div>
</div>

<div className="flex items-center gap-18px">
<PhoneIcon size="30px" />
<VideoIcon size="30px" />
</div>
</nav>
);
}

Choose a reason for hiding this comment

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

PR 코멘트에 /chat/{id} 페이지의 상단 navbar 프로필 사진과 이름을 클릭하면 상대방과 나 사이의 유저 전환이 가능하다고 적어주셨는데 전환 관련 함수가 빠져있는 것 같아요!

Comment on lines +54 to +55
onDoubleClick={() => reactToMessage(message.id, userId, '💖')}
>

Choose a reason for hiding this comment

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

반응 기능에서 메시지를 더블클릭하면 텍스트와 요소들이 파란색으로 드래그 되는 현상이 있습니다! 저도 이번주에 이모지 기능을 구현하면서 똑같이 겪었던 문제인데 event.preventDefault();를 사용하여 해결했습니다. 혹시 도움되실까 해서 코멘트 남깁니다!

Copy link

@s-uxun s-uxun left a comment

Choose a reason for hiding this comment

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

안녕하세요 다혜님!
이번 주 코드리뷰를 맡은 송유선입니다. 🤍

다혜님 코드에서는 늘 많은 경험이 묻어나는 것 같아요. 저는 테일윈드를 써본 적이 없는데 (태그 너무 길어지는 거 싫었어요...) 다혜님께서는 테일윈드도 최대한 깔끔하고 구조적으로 쓰시는 것 같아 많이 배웠습니다! 또 절대경로 설정하시는 거나, 커스텀 훅 만드시는 거나 여러모로 다양한 팁들을 많이 알고 계신 것 같아요 ㅎㅎ 다음 주 과제도 저희 함께 파이팅해요 🔥

@@ -0,0 +1,14 @@
const CracoAlias = require('craco-alias');
Copy link

Choose a reason for hiding this comment

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

절대 경로를 사용하셨네요..! 사실 전 대부분 컴포넌트화를 시켰기 때문에 import에서 경로가 자동으로 완성되니까 불편함을 못 겪다가.. 이번에 파일이 많아지면서 폴더 정리를 할 때 애를 먹었어요 😂... 파일을 다른 폴더로 옮기고 싶은데 그럼 경로를 하나하나 수정해줘야 하는 부분이 많아 번거롭더라구요... 그래서 다음엔 꼭 절대 경로를 써봐야겠다고 다짐했답니다. 다혜님께서는 이미 쓰고 계셨군요! 👍🏻

"eslint-plugin-react": "^7.36.1",
"eslint-plugin-react-hooks": "^4.6.2",
"prettier": "^3.3.3",
"tailwindcss": "^3.4.13"
Copy link

Choose a reason for hiding this comment

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

전 아직 styled-component가 좋은데.. 다들 테일윈드 추천하시더라구요... 저도 담 과제에서는 함 써볼까봐여

Copy link

Choose a reason for hiding this comment

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

쏘큩

border-b border-colors-blue_gray"
>
<div className="flex items-center gap-15px">
<BackIcon size="24px" />
Copy link

Choose a reason for hiding this comment

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

여기에 useNavigate를 활용해서 채팅방 목록으로 돌아가는 경로를 설정해주시면 더욱 좋을 것 같습니다! (+ 미리 navigate 선언하기 + 커서 포인터 추가)

Suggested change
<BackIcon size="24px" />
<BackIcon
size="24px"
onClick={() => navigate('/chat')}
style={{ cursor: 'pointer' }}
/>

Comment on lines +4 to +9
const defaultMessageText = `
relative
body2
w-fit max-w-256px px-12px py-8px
rounded-message-lg
break-keep whitespace-pre-wrap`;
Copy link

Choose a reason for hiding this comment

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

재사용 가능성이 있는 걸 미리 이렇게 정의하고 사용하니까 테일윈드 써도 꽤 깔끔하게 보이는 것 같아요..!

다만 제가 다혜 님 페이지를 테스트하다가 발견한 건데, 많은 텍스트를 입력하면 인풋창에는 잘 반영이 되는데 보내진 텍스트에는 반영이 안 되고 잘리더라구요,,, ㅜ

image
image

왜 이렇게 한 줄로만 보내지는지 알아보려고 해당 코드를 보니까, 아무래도 break-keep 때문인 것 같아요! 이게 텍스트를 특정 위치에서 강제로 줄바꿈하지 않도록 제한하는 역할을 하니까 한 줄로 나왔던 게 아닐까 합니다... 이 부분만 삭제하시면 텍스트가 말풍선에 제대로 다 담길 것 같아요 :)

그리고 메세지를 더블 클릭하면 반응을 달 수 있는데 지금은 커서가 그 텍스트 입력 모양의 커서라서 포인터로 바꾸면 사용자 관점에서 더욱 편리한 페이지가 될 것 같습니다!

Suggested change
const defaultMessageText = `
relative
body2
w-fit max-w-256px px-12px py-8px
rounded-message-lg
break-keep whitespace-pre-wrap`;
const defaultMessageText = `
relative
body2
w-fit max-w-256px px-12px py-8px
rounded-message-lg
whitespace-pre-wrap cursor-pointer`;


<div className="flex gap-10px">
<button type="button">
<img
Copy link

Choose a reason for hiding this comment

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

그리고 혹시 이번에는 왜 유저 전환 부분이 빠졌는지 알 수 있을까욥,,? 제가 못 찾은 걸 수도 있는데 .. 유저가 전환이 안 됩니당... 지난 번에 구현하셨던 것 같은데 그대로 두셨으면 더욱 좋았을 것 같아요🥲

Copy link

Choose a reason for hiding this comment

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

자주 쓰이는 걸 커스텀 훅으로 만든 부분 너무 좋은 것 같아요~~ 그리고 전 전부 그냥 냅다 tsx로 만들었는데ㅋㅋㅋ 다혜님께서 이걸 ts로 작성하신 것 보고 꼼꼼하시다고 느꼈어요 👍🏻

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