2025-07-23 14:36:23

🌿 Mori 개발 일지 - Day 20 (2025년 7월 23일)

📆 작성일: 2025년 7월 23일 (수)
🎯 작업 목표: 캘린더 반응형 개선 및 ResultMonthly.jsx 렌더링 문제 해결


✅ 오늘의 진행 내용 요약

항목 내용
📌 주요 파일 CalendarView.jsx, index.css, ResultMonthly.jsx, EmotionChart.jsx, LoadingDonut.jsx
🛠 핵심 수정 반응형 달력 리팩토링, 그래프 중복 렌더링 문제 해결, 실시간 UI 반영 로직 개선
🧪 테스트 환경 Chrome DevTools, Vite 개발 서버 (Hot Reloading)
📦 기타 전체 페이지 흐름 유지 및 스타일 통일화, 사용성 개선

🔧 주요 작업 상세 내역

1. 📅 CalendarView.jsx 반응형 레이아웃 리팩토링

  • 기존 문제: 모바일에서 달력이 우측으로 밀리는 현상 발생
  • 핵심 해결 방식:
    • aspect-square 사용해 정사각형 유지
    • min-width: 0으로 부모 컨테이너 영향 제거
    • grid grid-cols-7 구조로 날짜가 정렬되도록 유지
  • 수정된 코드 발췌:
<div
  key={`${type}-${day}-${i}`}
  className={... + " aspect-square"}
  style={{ minWidth: 0 }}
>
  • w-full px-2 max-w-sm mx-auto를 통해 모바일/데스크탑 모두 중앙 정렬 유지

2. 🎨 index.css 수정

  • 글로벌 스타일 bodyoverflow-x: hidden 추가
  • 기존의 Tailwind와 충돌하지 않게 유지하며, 의도치 않은 좌우 스크롤 방지
  • 커스텀 스크롤바 유지 및 감정 분석 박스에 사용
body {
  margin: 0;
  overflow-x: hidden;
}

3. 📊 ResultMonthly.jsx 2중 렌더링 현상 분석 및 수정

  • 문제: 감정 그래프가 처음엔 제대로 보이나, 두 번째 렌더링 시 1개만 출력됨
  • 테스트:
    • console.log(result.emotion)으로 로딩 중 2회 출력 확인
    • 상태가 두 번 세팅되면서 감정 배열이 덮여씀
  • 원인: summarizeWithGPT() 응답 객체가 매번 다르게 구조화됨 (객체 vs 배열)
  • 해결:
const sortedEmotions = Array.isArray(result.emotion)
  ? result.emotion
  : Object.entries(result.emotion || {}).sort(...);
  • 이후 setEmotions(sortedEmotions)로 불변성을 유지한 값만 저장

4. ✅ EmotionChart.jsx는 그대로 유지

  • 중요사항: ResultDaily.jsx와 공유하므로 절대 수정하지 않음
  • 파싱 구조 문제였음을 확인하고 부모 컴포넌트에서 해결

5. 🌀 LoadingDonut.jsx 문구 누락 이슈

  • 초기 로딩 중 “모리가 이번달 일기를 읽고 있어요” 텍스트가 사라짐
  • 원인: textLines props 전달 누락
  • 해결: ResultMonthly.jsx 내 조건부 렌더링 구조 수정
if (loading) {
  return (
    <LoadingDonut
      textLines={[
        "모리가 이번달 일기를",
        "읽고 있어요",
        "잠시 후 결과를 알려드릴게요",
      ]}
    />
  );
}

6. 🧼 달력 일기 삭제 시 즉시 UI 반영

  • 문제: 일기 삭제 후에도 파란 원(작성된 날짜 표시)이 유지됨
  • 원인: 상태 업데이트가 선택된 날짜 정보에만 반영됨. 전체 달력용 날짜는 갱신되지 않음
  • 해결:
const updatedDates = await getSummariesByMonth(user.id, currentYear, currentMonth);
setSummaryDates(updatedDates.map((d) => parseInt(d.split("-")[2])));
  • 이로 인해 모달에서 일기 삭제 시 즉시 달력 UI가 반영되도록 개선

7. 🔄 전체 페이지 레이아웃 흐름 유지

  • ResultDaily, ResultMonthly, CalendarView에 동일한 max-width, padding 적용
  • 상단 여백, 버튼 스타일, 도넛 위치, 그림자 효과까지 완전 통일

🐛 트러블슈팅 상세 분석

❗️[문제1] 캘린더 반응형이 적용되지 않음

  • w-10 h-10은 고정값으로 모바일에선 깨짐
  • aspect-square만 사용 시 부모가 비율 못 맞추면 깨짐
  • 테스트 흐름:
    1. w-10 h-10 → 반응형 깨짐
    2. aspect-square → 부모 공간 부족 시 깨짐
    3. min-width: 0 조합 → 해결됨

❗️[문제2] EmotionChart가 하나만 보임

  • summarizeWithGPT() 응답이 첫 번째는 정상, 두 번째는 객체 구조로 전달됨
  • 원인 분석:
    • 두 번째 응답에서 emotion 필드가 { 행복: 60, 슬픔: 40 } 형태로 옴
    • 이걸 setEmotions()에 넘기면 EmotionChart에서 map 돌릴 수 없어 하나만 출력됨
  • 해결 코드:
const sortedEmotions = Array.isArray(result.emotion)
  ? result.emotion
  : Object.entries(result.emotion || {}).sort(...);

❗️[문제3] useEffect가 두 번 실행되어 setState 중복됨

  • React 18에서 StrictMode 사용 중 useEffect 두 번 실행됨
  • 원인 확인: useEffect 로그 찍어보면 두 번 호출됨
  • 해결: loading 플래그로 조건 처리하거나 React Dev 환경에서는 허용
useEffect(() => {
  if (!user) return;
  fetchData();
}, [user]);

❗️[문제4] 도넛 문구가 안보임

  • 로딩 상태 조건부 렌더링에서 textLines 빠짐
  • 해결: ResultMonthly에서 loading 시 정확한 prop 전달로 복구

✏️ 오늘 작업의 의미

  • 모든 화면에서 통일된 경험 제공 (디자인, 구조, 로딩 흐름)
  • 달력 및 감정 분석 페이지의 UI, UX 정합성 완성
  • 불안정했던 렌더링 순서와 데이터 전달 구조의 근본적인 안정화 완료

🧭 다음 작업 (Day 21, 7월 24일)

  • 전체 QA 테스트 (반응형 + 페이지별 이동 + 데이터 흐름)
  • console.log 제거 및 경량화
  • 최종 Vercel 배포 준비

현재 시연 영상

'사이드프로젝트' 카테고리의 다른 글

[Mori] Final  (1) 2025.07.28
[Mori] 17일차  (3) 2025.07.25
[Mori] 15일차  (0) 2025.07.22
[Mori] 14일차  (1) 2025.07.18
[Mori] 13일차  (1) 2025.07.17