나의 개발일지

react-calendar 리액트 달력 적용하기 / 컨텐츠 추가하기 📆 본문

라이브러리

react-calendar 리액트 달력 적용하기 / 컨텐츠 추가하기 📆

heew0n 2024. 1. 6. 03:15

프로젝트에 캘린더 기능을 추가하도록 했다

우선 결과물이다 (완벽하게 완성된 것은 아님!)

 

 

 

환경오염을 줄이는 습관을 공유하는 글을 쓰면 캘린더에 아이콘으로 표시가 되고

그 밑 숫자는 글 쓴 횟수를 나타냈다

 

react-calendar를 쓰기 위해서는 설치를 해주어야 한다

 

npm일 경우,

npm install react-calendar

 

yarn일 경우,

yarn add react-calendar

 

 

기본 코드 작성

import React, { useState } from 'react';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';

const HabitCalendar = ({ date }: any) => {
  // 초기값은 현재 날짜
  const [today, setToday] = useState<Value>(new Date());
  //클릭한 캘린더의 날짜를 알려줌
  const moment = require('moment');
  const onChangeToday = () => {
    setToday(today);
  };
  
  // DB에서 작성한 posts를 가져온다
  const { data } = useQuery({
    queryKey: [QUERY_KEYS.POSTS],
    queryFn: getMyPosts
  });
  
  // 저장해둔 getFormattedDateCustom에 맞춰 posts의 createdAt을 날짜 형태로 바꿔준다
 const createdAtList = data ? data.map((data) => getFormattedDateCustom(data.createdAt!)) : [];

 

 

createdAt을 콘솔에 찍어보면 이렇게 나온다

 

 

  const getElCount = (arr: string[]): Record<string, number> =>
    arr.reduce((ac: Record<string, number>, v) => {
      ac[v] = (ac[v] || 0) + 1;
      return ac;
    }, {});
  const dayCount = getElCount(createdAtList);
  console.log('dayCount', dayCount);

 

posts 배열에서 중복되는 값의 갯수를 찾는 함수이다

 

 

  <Calendar
  onChange={onChangeToday}
          value={today}
          // eng 버전
          locale="en"
          // 일요일부터 시작
          calendarType="gregory"
// 날짜에 컨텐츠 추가하기
tileContent={({ date, view }) => {
       const formattedDate = moment(date).format('YYYY. MM. DD.')
          if (createdAtList.find((x) => x === moment(date).format('YYYY. MM. DD.'))) 
             const postCount = dayCount[formattedDate] || 0;
   />

 

 

여기서 말도 안되는 실수를 하고야 만다

 

const formattedDate = moment(date).format('YYYY. MM. DD ') 

맞는 로직 같은데 결과가 이상하게 출력이 되었다. 

알고보니 DD 뒤에 .을 안 찍어서.....

허무했다

그래서 오류가 안 나지만 원하는 결과가 나오지 않을 때

하나하나 콘솔에 찍고 비교해가며 오류를 잡아내야 한다..

 

 

     // postCount가 0으로만 나온다.
     // dayCount[formattedDate]가 값이 없으니까 => 0으로 된다?
     // dayCount에 문제가 있는지?
     // formattedDate에 문제가 있는지?
    console.log({
          formattedDate,
          finded: createdAtList.find((x) => x === moment(date).format('YYYY. MM. DD')),
         일치하는지: formattedDate === dayList.find((x) => x === moment(date).format('YYYY. MM. DD.'))
      });

 

 

 

 <div className="habitDayContainer" key={formattedDate}></div>
                  <img
                    key={formattedDate}
                    className="habitImage"
                    src={mangoIcon}
                    alt={`habit-sticker-${formattedDate}`}
                  />
                  x {postCount}

 

컨텐츠에 이미지를 삽입했다

그리고 이미지 뒤에 posts의 갯수를 나타내어 완성할 수 있었다

 

 

 


 

 

 

거의 완성된 캘린더 모습이다.

z-index를 사용하여 postcount와 spring을 구현했는데 꽤 오래걸렸던 작업이었다.

튜터님의 피드백으로는 사용자가 이 달력의 용도가 뭔지 잘 모를 것 같다고 하여

캘린더를 소개하는 글도 위에 쓸 예정이다.