본문 바로가기
반응형

저번 1편에 이어서 2편으로 date-fns와 Style-Components로 커스텀 달력 편을 마무리 하고자 합니다!

2023.07.06 - [코딩/Javascript] - [React] date-fns와 style-components로 커스텀 달력 만들기(1편)

 

[React] date-fns와 style-components로 커스텀 달력 만들기(1편)

올해 새로운 프로젝트를 맡게 되면서 달력에 서버에 있는 데이터를 보여줘야하는 기능을 구현하게 되었다. 다양한 라이브러리가 있었지만 디자이너의 요구에 맞는 달력을 제작하기가 어려워 da

quddkflty.tistory.com

 

커스텀 달력 만들기

이제 date-fns에 대한 이해도가 어느 정도 생겼다는 가정하에 글을 쓰도록 하겠다.

 

1. Date-fns 라이브러리 설치 후 사용할 함수 Import하기

  • 라이브러리 설치하기
npm install date-fns --save
# or with yarn
yarn add date-fns
  • 달력 기능을 위한 라이브러리 Import하기 
    • Import한 함수들에 대한 이해를 위해 예시 코드를 참고하시길 바랍니다. 
import {
  format,
  addMonths,
  subMonths,
  startOfWeek,
  endOfWeek,
  startOfMonth,
  endOfMonth,
  eachDayOfInterval,
  isSameMonth,
  isSameDay,
} from "date-fns";
import { ko } from "date-fns/locale";
더보기
import {
  format,
  addMonths,
  subMonths,
  startOfWeek,
  endOfWeek,
  startOfMonth,
  endOfMonth,
  eachDayOfInterval,
  isSameMonth,
  isSameDay,
} from "date-fns";
import { ko } from "date-fns/locale";

// 날짜 포맷하기
const formattedDate = format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ko });
// format 함수를 사용하여 현재 날짜와 시간을 한국 시간으로 포맷합니다.
// "yyyy-MM-dd HH:mm:ss" 형식은 년-월-일 시:분:초 형태로 날짜를 표현합니다.
// format 함수의 첫 번째 인수로는 날짜 객체를 전달하고, 세 번째 인수로는 로캘(locale) 객체를 전달합니다.

// 월 추가/감소
const nextMonth = addMonths(new Date(), 1);
const previousMonth = subMonths(new Date(), 1);
// addMonths 함수와 subMonths 함수를 사용하여 현재 날짜에서 월을 추가하거나 감소시킵니다.
// 첫 번째 인수로는 날짜 객체를 전달하고, 두 번째 인수로는 추가하거나 감소시킬 개월 수를 전달합니다.

// 주의 시작과 끝 계산
const weekStart = startOfWeek(new Date(), { weekStartsOn: 1 });
const weekEnd = endOfWeek(new Date(), { weekStartsOn: 1 });
// startOfWeek 함수와 endOfWeek 함수를 사용하여 현재 날짜를 기준으로 주의 시작과 끝을 계산합니다.
// weekStartsOn 옵션을 사용하여 주의 시작 요일을 설정할 수 있습니다. (1은 월요일, 0은 일요일)

// 달의 시작과 끝 계산
const monthStart = startOfMonth(new Date());
const monthEnd = endOfMonth(new Date());
// startOfMonth 함수와 endOfMonth 함수를 사용하여 현재 날짜를 기준으로 달의 시작과 끝을 계산합니다.

// 두 날짜 사이의 모든 날짜 가져오기
const intervalDays = eachDayOfInterval({ start: new Date(2023, 0, 1), end: new Date(2023, 0, 7) });
// eachDayOfInterval 함수를 사용하여 두 날짜 사이의 모든 날짜를 가져옵니다.
// start와 end 옵션을 사용하여 날짜의 범위를 지정합니다.

// 두 날짜가 같은 달인지 확인
const isSameMonthResult = isSameMonth(new Date(), new Date(2023, 0, 1));
// isSameMonth 함수를 사용하여 두 날짜가 같은 달인지 확인합니다.

// 두 날짜가 같은 날인지 확인
const isSameDayResult = isSameDay(new Date(), new Date(2023, 0, 1));
// isSameDay 함수를 사용하여 두 날짜가 같은 날인지 확인합니다.

 

2. 오늘의 날짜가 껴있는 달의 날짜들을 가져오기

  • 현재 달에 대한 useState 설정
  const [currentMonth, setCurrentMonth] = useState(new Date());
  • startOfWeek(), startOfMonth() 함수를 사용해서 현재 달의 시작 날짜와 마지막 날짜를 설정한 후 return 해준다.
  const getCalendarDays = () => {
    const startDate = startOfWeek(startOfMonth(currentMonth));
    const endDate = endOfWeek(endOfMonth(currentMonth));

    const days = eachDayOfInterval({ start: startDate, end: endDate });

    return days;
  };
  • days에 대한 값을 받아온 후 map 함수를 통해 포맷한 형식에 맞게 날짜들을 나열한다. 
    여기서 <Day> 컴포넌트는 Style-components로 원하는 디자인에 맡게 설정하면 된다. 
    istoday() 함수를 props 값에 전달하여 오늘 날짜에 대한 css를 추가하여 보여줄 수 있다.
 const renderCalendarDays = () => {
    const days = getCalendarDays();

    return days.map((day) => {
      const formattedDate = format(day, "yyyy-MM-dd");
      const eventData = data.find((item) => item.date === formattedDate);

      return (
        <Day
          key={day}
          iscurrentmonth={isSameMonth(day, currentMonth)}
          istoday={isSameDay(day, new Date())}
        >
        </Day>
      );
    });
  };

 

  • 버튼 클릭으로 이전 달, 다음 달 이동하기 
    useState를 사용해서 현재 달에 대해 값에 +/- 1을 통해 원하는 달로 이동할 수 있다. 
 const handlePrevMonth = () => {
    setCurrentMonth(subMonths(currentMonth, 1));
  };

  const handleNextMonth = () => {
    setCurrentMonth(addMonths(currentMonth, 1));
  };

전체 코드

  const [currentMonth, setCurrentMonth] = useState(new Date());


const handlePrevMonth = () => {
    setCurrentMonth(subMonths(currentMonth, 1));
  };

  const handleNextMonth = () => {
    setCurrentMonth(addMonths(currentMonth, 1));
  };

  const getCalendarDays = () => {
    const startDate = startOfWeek(startOfMonth(currentMonth));
    const endDate = endOfWeek(endOfMonth(currentMonth));

    const days = eachDayOfInterval({ start: startDate, end: endDate });

    return days;
  };

  const renderCalendarDays = () => {
    const days = getCalendarDays();

    return days.map((day) => {
      const formattedDate = format(day, "yyyy-MM-dd");
      const eventData = data.find((item) => item.date === formattedDate);

      return (
        <Day
          key={day}
          iscurrentmonth={isSameMonth(day, currentMonth)}
          istoday={isSameDay(day, new Date())}
        >
        </Day>
      );
    });
  };

 

우리 프로젝트에서는 특정 날짜를 클릭하면 해당 날짜에 있는 event가 뜨고, event가 있는 날짜들에 대해 하이라이트 표시를 확인할 수 있도록 설정해놓았는데 다음 편에서 설명하도록 하겠다.

모두 화이팅 :)

2023.07.08 - [분류 전체보기] - [React] date-fns와 Style-Components로 커스텀하기 쉬운 달력 만들기 (3편 - 오늘 표시하기 + Event 날짜 표시)

 

[React] date-fns와 Style-Components로 커스텀하기 쉬운 달력 만들기 (3편 - 오늘 표시하기 + Event 날짜 표

이번 편에서는 특정 날짜를 클릭하면 해당 날짜에 있는 event가 뜨고, event가 있는 날짜들에 대해 하이라이트 표시를 확인할 수 있도록 설정하는 방법을 말씀해드리겠습니다.. 저는 Props와 hook(UseSt

quddkflty.tistory.com

 

반응형