Skip to content

[4주차] 신수진 미션 제출합니다. #18

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 18 commits into
base: master
Choose a base branch
from

Conversation

lemoncurdyogurt
Copy link

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

일단 이전 주차에서의 파일 구조 리팩토링과, 아이콘들 svg파일로 다시 다운받으면서 svg?react 형식으로 수정하여 활용하였으며, 나머지 구현이 안된 부분들을 마저 구현하고자 하였습니다.
시험이 끝난지 얼마 안돼서, 시간이 부족한 이슈로 급하게 과제를 수행하느라 아직 디자이너분이 제시한 화면과 다른 점이 조금 있습니다. 월요일 프론트엔드 세션 전까지 계속 코드 수정하고자합니다.

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

동적 라우팅은 애플리케이션의 라우트를 정적으로 설정하는 대신, 애플리케이션 실행 중에 라우트를 동적으로 변경하거나 추가하는 방식. 일반적으로 React Router에서는 Route 컴포넌트를 사용해 라우팅을 설정합니다. 동적 라우팅을 사용하면 URL 경로에 따라 컴포넌트나 페이지를 동적으로 렌더링할 수 있음.

사용 예시:

  • 조건부 렌더링: 사용자의 권한에 따라 특정 페이지로의 접근을 제한하거나 다른 컴포넌트를 렌더링하고 싶을 때.
  • 파라미터 기반 라우팅: URL 경로에 포함된 동적 파라미터를 기반으로 다른 내용을 보여줄 때. 예를 들어, 블로그 페이지에서 각 글의 ID를 URL 경로에 포함시켜 해당 글을 표시하는 경우.
<Route path="/profile/:id" component={Profile} />

위와 같은 라우팅 설정은 /profile/1, /profile/2와 같은 동적 URL에 따라 Profile 컴포넌트를 다르게 렌더링할 수 있다.


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

UI/UX 디자인 전략:

  • 로딩 인디케이터: 사용자가 네트워크가 느린 환경에서 기다리고 있음을 알리기 위해 로딩 스피너나 진행 바를 사용하여 기다리는 시간 동안 사용자가 불편하지 않도록 함.
  • UI 구성 요소 지연 로딩(Lazy Loading): 필요한 리소스만 로드하고, 나머지는 사용자가 필요로 할 때 로드합니다. 이를 통해 초기 로딩 시간을 줄일 수 있음.
  • 시각적 피드백 제공: 네트워크 요청이 지연될 경우 "잠시만 기다려 주세요"와 같은 피드백을 통해 사용자가 대기하는 이유를 이해할 수 있게 함.
  • Progressive Disclosure: 필요한 정보만 단계적으로 노출하여 불필요한 정보가 초기 화면에 로딩되지 않도록 함.

기술적 최적화 방법:

  • 서비스 워커(Progressive Web App): 캐싱 및 백그라운드 데이터를 미리 가져오는 방법을 통해 네트워크 속도가 느린 환경에서도 애플리케이션을 원활하게 사용할 수 있도록 함.
  • 이미지 최적화: 이미지 파일 크기를 줄여서 로딩 속도를 개선합니다. 다양한 해상도에 맞는 이미지를 로드하는 srcset을 사용하거나, 이미지 압축 기술을 활용함.
  • API 요청 최적화: 데이터 요청을 최소화하고, 데이터 페칭을 효율적으로 처리하기 위해 GraphQL이나 REST API에서 필요 최소한의 데이터만 요청하도록 함.
  • 코드 스플리팅(Code Splitting): 초기 로딩 시간을 줄이기 위해 JavaScript 파일을 여러 개로 나누고, 사용자가 필요로 할 때만 로드하도록 설정함.

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

  • useState: 컴포넌트 내에서 단일 상태를 관리할 때 사용합니다. 간단한 상태 변경에 적합하며, 값이 바뀔 때마다 컴포넌트를 리렌더링함.

    const [count, setCount] = useState(0);
  • useReducer: 상태가 복잡하거나 여러 액션에 의해 상태가 변경될 때 유용합니다. useState보다 더 복잡한 로직을 필요로 할 때 사용하며, 상태 관리가 여러 조건에 따라 이루어지는 경우에 적합함.

    const initialState = { count: 0 };
    function reducer(state, action) {
      switch (action.type) {
        case 'increment':
          return { count: state.count + 1 };
        case 'decrement':
          return { count: state.count - 1 };
        default:
          return state;
      }
    }
    
    const [state, dispatch] = useReducer(reducer, initialState);
  • Context API: 여러 컴포넌트에 걸쳐 상태를 공유할 때 유용합니다. Context를 사용하면 prop drilling(중간 컴포넌트를 통해 데이터를 전달)을 피할 수 있으며, 앱 내에서 전역 상태를 관리할 수 있습니다. 그러나 Context API는 너무 자주 변경되는 상태를 다루기에는 성능 이슈가 있을 수 있음.

    const MyContext = React.createContext();
    
    function MyComponent() {
      const value = useContext(MyContext);
      return <div>{value}</div>;
    }
  • 전역 상태 관리 라이브러리 (예: Redux, Zustand, Recoil 등): 앱의 전역 상태를 보다 효율적으로 관리하기 위해 사용됩니다. 여러 컴포넌트에서 상태를 공유하고 업데이트해야 할 때 강력한 도구가 됩니다. 일반적으로 Redux 같은 라이브러리는 복잡한 상태 관리 로직을 처리할 수 있도록 돕습니다. 또한, Redux는 상태를 관리하는 중앙 스토어를 제공하고, Actions를 통해 상태를 변경함.

    // Redux Example
    const initialState = { count: 0 };
    function counterReducer(state = initialState, action) {
      switch (action.type) {
        case 'increment':
          return { count: state.count + 1 };
        case 'decrement':
          return { count: state.count - 1 };
        default:
          return state;
      }
    }

Copy link

@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.

시험과 과제 모두 수고하셨습니다 !! 🥲

Choose a reason for hiding this comment

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

레이아웃 관련 로직은 따로 컴포넌트로 분리해서 import 하여 작성하는 게 유지보수나 확장성 면에서 더 좋을 것 같습니다!
그리고 스플래시 화면은 화면을 새로고침할 때마다 뜨는 것 같아서, 혹시 앱을 처음 실행할 때만 뜨는 화면이 아닌지 궁금합니당
코드 로직을 보았을 때 채팅방이나 채팅 리스트에서도 새로고침을 했을 때 화면이 뜨는 것 같아서요!

Comment on lines +3 to +6
import HomeIcon from "../assets/icons/TabBar/Home.svg?react";
import PhoneIcon from "../assets/icons/TabBar/Phone.svg?react";
import SpeechBubbleIcon from "../assets/icons/TabBar/SpeechBubble.svg?react";
import ServiceIcon from "../assets/icons/TabBar/Service.svg?react";

Choose a reason for hiding this comment

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

추후 파일과 코드가 많아지면, 절대 경로를 사용하는 방식을 적용해보는 것도 좋을 것 같습니다 :)
그동안 절대 경로로 코드를 작성하면서 느낀 바로는, 상대 경로에서 발생할 수 있는 경로 오류나 관리의 어려움을 방지할 수 있었고, 코드의 가독성도 높아져서 유지보수와 확장성 측면에서 도움이 될 수 있었습니다 !!

Comment on lines +3 to +6
"roomId": 1,
"allChats": [
{
"date": "2025년 3월 26일 수요일",

Choose a reason for hiding this comment

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

실제 백엔드 API를 호출할 때는 ISO 날짜 형식을 받아와 프론트에서 가공하는 함수를 작성하는 경우가 많으니, 목데이터에서도 해당 형식을 그대로 사용해서 함수를 작성해보아도 좋을 거 같습니다!

Comment on lines +9 to +37
const TabBarWrapper = styled.div`
position: absolute;;
bottom: 0;
left: 0;
right: 0;
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
height: 60px;
border-top: 1px solid #ddd;
background-color: white;
`;

const IconWrapper = styled.div<{ $active: boolean }>`
display: flex;
flex-direction: column;
align-items: center;
color: ${({ $active }) => ($active ? "black" : "gray")};
font-size: 12px;
transition: color 0.3s ease;

svg {
width: 24px;
height: 24px;
fill: #ffffff // 아이콘 색
margin-bottom: 4px;
}
`;

Choose a reason for hiding this comment

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

코드가 짧긴 하지만, 스타일 파일로 별도 분리해도 좋을 거 같아요!

isFixed: boolean;
}

const ChatRoomList: React.FC = () => {

Choose a reason for hiding this comment

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

최근에는 React.FC를 사용하지 않는 것이 더 권장되는 방식으로 여겨지고 있는데, 관련 링크 첨부해드립니다!

React.FC 링크

`;

export const SplashContainer = styled.div`
animation: ${fadeIn} 1.5s ease-in-out;

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.

로컬에서 실행했을 때 콘솔에 해당 오류가 나는데, iscurrentuser를 전달해줄 때 앞에 $를 붙이면 DOM으로 전달되지 않아 경고문을 해결할 수 있습니다 ! 관련 블로그 남겨두겠습니당
BLOG

스크린샷 2025-04-28 오후 3 36 52

Choose a reason for hiding this comment

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

스크린샷 2025-04-28 오후 3 49 47 스크린샷 2025-04-28 오후 3 49 44

스플래시 화면과 다른 화면들의 레이아웃 높이 설정이 다른 것 같은데 통일시키면 좋을 것 같습니다!

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.

스타일은 별도 파일로 분리하고, 함수 이름은 friendList처럼 파일명과 일치하는 네이밍을 주로 사용하는 것을 권장드려요 !!

Choose a reason for hiding this comment

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

맨 마지막 친구까지 스크롤했을 때 바로 하단에 TabBar가 붙는 느낌이 들어서, 하단에 여백을 추가해주는 것도 좋을 것 같습니다.

allChats: AllChats[];
}

const ChatRoomDetail: React.FC = () => {

Choose a reason for hiding this comment

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

파일명과 일치시키는 것이 일관성 유지에 좋을 것 같습니다!

Comment on lines +217 to +222
<input
type="text"
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
placeholder="메시지를 입력하세요"
/>

Choose a reason for hiding this comment

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

채팅방에서는 장문의 텍스트를 입력하는 경우가 많기 때문에, textarea를 사용하여 작성한 글을 바로 보여주는 방식이 사용자에게 더 직관적이고 편리할 것 같습니다.
또한, enter 키를 눌렀을 때 메시지가 전송되고, shift + enter를 눌렀을 때 줄바꿈이 되도록 설정하면, 사용자가 자연스럽게 채팅을 작성할 수 있을 것 같습니당

추가로,, textarea의 높이는 작성하는 텍스트의 양에 맞춰 자동으로 조정되면 사용자 경험이 더 향상될 것 같습니다 !!

@chaeyoungwon
Copy link

chaeyoungwon commented Apr 28, 2025

vercel 설정 파일 추가해서 새로고침 되도록 해야 할 것 같아용
추가로, styled-components가 이제 업데이트가 안된다고 하니 tailwindcss도 사용해보시는 걸 추천드려요!
https://opencollective.com/styled-components/updates/thank-you

}
};

const handleBackClick = () => {

Choose a reason for hiding this comment

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

뒤로가기는 navigate(-1)로 작성해도 좋을 것 같아용

gap: 0.75rem;
`;

export const BackIcon = styled.img`

Choose a reason for hiding this comment

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

cursor:pointer를 추가해도 좋을 것 같습니당

Comment on lines +73 to +77
font-family: Pretendard;
font-size: 0.9375rem;
font-weight: 400;
line-height: 140%;
letter-spacing: -0.00094rem;

Choose a reason for hiding this comment

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

이런 스타일들은 font 관련 theme를 따로 설정해서, 매번 코드마다 직접 작성하지 않고 편하게 사용할 수 있습니다 !!

Choose a reason for hiding this comment

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

스타일은 별도 파일로 분리하고, 함수 이름은 friendList처럼 파일명과 일치하는 네이밍을 주로 사용하는 것을 권장드려요 !!

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