Skip to content

[4주차] 김민서 과제 제출합니다.#20

Open
minseo0614 wants to merge 67 commits intoCEOS-Developers:masterfrom
minseo0614:minseo
Open

[4주차] 김민서 과제 제출합니다.#20
minseo0614 wants to merge 67 commits intoCEOS-Developers:masterfrom
minseo0614:minseo

Conversation

@minseo0614
Copy link
Copy Markdown

@minseo0614 minseo0614 commented Apr 25, 2026

배포 링크

🔗 Slack Redesign


느낀점

  • React Router의 동적 경로와 localStorage를 결합하니 SPA에서도 자연스러운 영속성을 만들 수 있었습니다. /dms/:roomId 경로와 messages-${roomId} 키 분리를 통해, 새로고침이나 다른 탭에서 같은 URL로 들어와도 대화 내용이 그대로 유지되도록 구현했습니다.
  • 상태의 "범위"를 의식적으로 구분하게 되었습니다. 입력값·토글처럼 한 컴포넌트에 닫힌 상태는 useState로, 메시지 영속화는 localStorage로 분리하여 굳이 전역 상태 라이브러리를 도입하지 않았습니다. 작은 프로젝트라도 상태 관리 전략을 처음부터 명확히 정해두는 것이 중요하다는 것을 배웠습니다.

Review Questions

1. React Router의 동적 라우팅(Dynamic Routing)이란?

URL 경로의 일부를 변수처럼 받아서 같은 컴포넌트가 파라미터에 따라 다른 데이터를 렌더링하도록 하는 라우팅 방식입니다. 정적으로 모든 경로를 일일이 정의하지 않고, :param 형태의 placeholder로 매칭합니다.

// 라우트 정의
<Route path="/dms/:roomId" element={<ChatRoomPage />} />

// 컴포넌트에서 파라미터 추출
const { roomId } = useParams<{ roomId: string }>()

언제 사용하는가

  • 게시글 상세, 사용자 프로필처럼 동일한 UI 구조에 데이터만 다른 페이지
  • 채팅방처럼 항목 개수를 미리 알 수 없는 리소스
  • URL 자체가 자원의 식별자(/dms/room-1)가 되어 공유·새로고침에도 같은 화면 복원이 가능해야 할 때

본 프로젝트에서는 /dms/:roomId로 채팅방을 식별하여, URL만으로 특정 방을 직접 열 수 있게 구현했습니다.


2. 느린 네트워크 환경에서의 UX 개선 전략

UI/UX 디자인 전략

  • 스켈레톤 UI / 플레이스홀더: 빈 화면 대신 레이아웃 윤곽을 먼저 그려 체감 대기 시간 감소
  • 낙관적 업데이트(Optimistic UI): 서버 응답 전에 메시지를 먼저 화면에 띄우고, 실패 시 롤백
  • 점진적 노출(Progressive disclosure): 텍스트 → 저화질 이미지 → 고화질 순으로 단계적 로드
  • 명확한 로딩 상태와 에러 피드백: 무한 스피너 대신 진행률·재시도 버튼 제공

기술적 최적화

  • 코드 스플리팅 + Lazy Loading (React.lazy, Suspense)로 초기 번들 축소
  • 이미지 최적화: WebP/AVIF, loading="lazy", srcset으로 적절한 해상도 제공
  • 캐싱 전략: HTTP 캐시 헤더, Service Worker, React Query / SWR의 stale-while-revalidate
  • 번들 최적화: tree shaking, 압축(Brotli/Gzip), CDN 활용
  • 데이터 단위 축소: GraphQL이나 필드 선택으로 over-fetching 방지, 페이지네이션·무한 스크롤
  • Prefetch / Preload: 사용자가 다음에 볼 가능성이 높은 리소스를 미리 가져오기

3. useState / useReducer vs Context API / 전역 상태 라이브러리

구분 useState useReducer Context API 전역 상태 라이브러리 (Redux, Zustand 등)
범위 컴포넌트 지역 컴포넌트 지역 트리 일부 ~ 전역 앱 전역
적합한 상태 단순한 값 복잡한 전이 규칙 자주 안 변하는 공유 값 빈번하게 바뀌는 공유 값
업데이트 방식 setter 호출 action dispatch Provider value 갱신 store 구독·셀렉터
리렌더 범위 해당 컴포넌트 해당 컴포넌트 Provider 하위 전체 구독한 부분만 (셀렉터 단위)

useState — 토글, 입력값처럼 로직이 단순하고 한 컴포넌트에 닫혀 있을 때 사용

useReducer — 상태 전이가 여러 액션 타입으로 분기되거나, 다음 상태가 이전 상태에 의존하는 등 로직이 복잡할 때 적합합니다. action 단위로 의도가 명시적이라 테스트·디버깅에 유리

const [state, dispatch] = useReducer(reducer, initialState)
dispatch({ type: 'SEND_MESSAGE', payload: text })

Context APIprops drilling을 피하기 위한 값 전달 메커니즘이지 상태 관리 도구가 아닙니다. 값이 자주 바뀌면 Provider 하위 전체가 리렌더되므로 테마·로케일·인증 정보처럼 변경이 드문 값에 적합

전역 상태 라이브러리 (Redux, Zustand, Jotai 등) — 다음 요구가 동시에 필요할 때 도입

  • 여러 페이지/도메인에 걸친 광범위 공유 상태
  • 빈번한 업데이트선택적 구독(셀렉터)으로 불필요한 리렌더 방지
  • 미들웨어, 시간 여행, devtools 등 복잡한 사이드 이펙트 관리

@minseo0614 minseo0614 changed the title [1주차] 김민서 과제 제출합니다. [4주차] 김민서 과제 제출합니다. Apr 25, 2026
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.

1 participant