티스토리 뷰

이번 프로젝트에서 데이터의 날짜를 활용하는 동작이 많아 따로 정리해보려 한다.

배포 링크는 이전 게시물에서!

2023.12.11 - [코딩/프로젝트] - [개인 프로젝트] 투두 다이어리 (feat.Redux-Toolkit으로 여러 개의 상태 관리하기)

 


✏️ 투두 페이지 - 하루 데이터만 보여주기 

 

캘린더에는 작성된 모든 투두가 보여지지만 투두 페이지로 가면 투두 데이터가 보이지 않는다.

 

프로젝트를 구상할 때 하루가 지나면 이전에 기록된 투두는 수정이 불가능하고 새로운 날짜에 맞는 투두를 작성하도록 구현하고 싶었다.

(별다른 이유는 없고 그냥 그러고 싶었다,,, )

 

1. new Date()로 현재 날짜 가져오기 

new Date()를 사용해 현재 날짜를 받아와 투두 헤더에 날짜를 표시해준다.

  const date = new Date();
  const year = date.getFullYear();
  const month =
    date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1;
  const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate();
  const todayDateString = `${year}-${month}-${day}`;

년도, 월, 일을 각각 getFullYear, getMonth, getDate 메소드로 가져와 사용했다.

 

 

 

 

2. 투두 작성 시간 넘겨주기 

투두 데이터는 id, date, importance, text로 구성되어 있다.

프로젝트에서 상태 관리를 redux-toolkit으로 하고 있기 때문에 payload에 데이터를 담아 넘겨주어야 한다.

이때, redux의 규칙 중 하나인 '리듀서는 순수한 함수이어야 한다'를 지켜야 한다.

 

따라서 date 객체를 직렬화한 다음 보내준다.

const todoData = {
  id: id,
  date: date.toISOString(), // 직렬화 후 보내기
  importance,
  text,
};

 

 

 

 

3. toISOString( ) 시차 해결하기 

투두 데이터를 보낸 다음 데이터를 찍어보면 현재 시각과 투두의 date와 9시간의 시차가 존재한다.

이는 toISOString() 함수가 UTC 시간대를 기준으로 하기 때문이다.

따라서 두 시간에 대한 편차를 다루는 오프셋을 추가해준다.

// getTimezoneOffset()은 현재 시간과의 차이를 분 단위로 반환한다.
const offset = new Date().getTimezoneOffset() * 60000;

const itemDate = new Date(Date.now() - offset);
const todoData = {
  id: id,
  date: itemDate.toISOString(), // 직렬화 후 보내기
  importance,
  text,
};

 

 

 

 

 

4. 오늘 날짜에 해당하는 투두 데이터만 뽑아오기 

먼저 todayDateString과 투두의 date를 직렬화해 찍어본다.

const date = new Date();
const year = date.getFullYear();
const month =
date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : date.getMonth() + 1;
const day = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate();
const todayDateString = `${year}-${month}-${day}`;
console.log('todayDateString :', todayDateString);
  
const todayTodos = todos.map((it) => {
const todoDate = new Date(it.date);
console.log('todoDate :', todoDate.toISOString());
});

 

두 값 모두 'YYYY-MM-DD'의 형태를 띄고 있다.

 

형태를 확인한 다음 오늘 날짜와 같은 날짜를 가진 투두만 뽑아 배열로 만든다.

todoDate 중 필요한 부분만 짤라 새로 담아 비교했다.

const todayTodos = todos.filter((it) => {
    const todoDate = new Date(it.date);
    const todoDateString = todoDate.toISOString().slice(0, 10);

    return todoDateString === todayDateString;
});

 

 

 

5. 완성된 화면 

12월 13일에 작성된 투두 데이터만 보여진다!

 

 


 

✏️ 캘린더 페이지 - 투두 작성 날짜에 맞게 보여주기 

 

투두가 작성되고 나면 캘린더에 투두가 작성된 날짜에 맞게 개수가 표시된다.

 

프로젝트를 구상하면서 가장 구현하고 싶었던 부분이다!

하루가 지나면 투두가 보이지 않기 때문에 이전에 작성되었던 투두를 표시하기 위한 방법으로

캘린더에 투두를 표시해 볼 수 있도록 구현하고 싶었다.

 

또 투두의 완료 여부에 따라 완료 투두/ 미완료 투두로 나누어 데이터를 표시해 한 눈에 볼 수 있도록 구현했다.

 

 

1. 투두 데이터를 날짜에 따라 카운트하기 

투두 데이터를 useSelector로 가져온 다음 캘린더의 이벤트로 넣어주기 전 날짜에 따라 투두의 수를 카운팅한 객체를 생성한다.

 

reduce 메소드로 transformedEvents를 같은 날짜의 투두 데이터의 수를 카운팅하는 방법을 사용했다.

const events = useSelector((state) => state.todo.data);

const eventCountsByDate = events.reduce((acc, event) => {
const dateKey = new Date(event.date).toISOString().slice(0, 10);
acc[dateKey] = (acc[dateKey] || 0) + 1;
return acc;
}, {});

먼저 event의 date를 년, 월, 일만 사용하기 때문에 slice로 잘라 가져온다.

이벤트의 날짜를 키로 가진 객체를 만들어 존재하는 키의 경우에는 현재값에 +1, 존재하지 않다면 0부터 시작해 +1을 더한 값을 할당한다.

 

반환된 객체를 찍어보면 날짜가 키로, 해당 날짜에 작성된 투두가 개수로 들어와있다.

 

 

 

 

 

2. 날짜 카운트 객체를 이벤트로 넣어주기 

eventCoutsByDate 객체를 캘린더에 표시하려면 이벤트로 넣어주어야 한다.

 

표시될 title은 카운팅된 수를 넣어 투두의 개수를 보여주었다.

const eventCountArray = Object.entries(eventCountsByDate).map(
    ([date, count]) => ({
      id: date,
      title: `${count}개`,
      start: new Date(date).toISOString(),
      end: new Date(date).toISOString(),
      allDay: true,
    }),
);

 

 

 

 

+ 이벤트를 누르면 해당 날짜의 투두 목록을 보여주는 페이지로 이동하기 

이벤트를 눌러 투두 목록을 보여주는 페이지로 이동하기 위해 onSelectEvent 속성을 사용했다.

 

onSelectEvent는 클릭된 이벤트에 대한 정보를 매개변수로 전달한다.

여기서 전달받은 이벤트의 start 프로퍼티를 가져와 경로 파라미터로 사용했다.

const handleCellClick = ({ start }) => {
    const formattedDate = new Date(start).toISOString().slice(0, 10);
    nav(`/calendar/${formattedDate}`);
};

 

 

 

 


🔗 참고 링크 

https://velog.io/@zad1264/Date.toISOString-%EC%98%A4%ED%94%84%EC%85%8B-%EB%A7%9E%EC%B6%94%EA%B8%B0

 

Date.toISOString 오프셋 맞추기

Date객체가 반환하는 날짜와 toISOString() 함수의 반환값은 다르다.지금 글을 쓰는 시간 기준으로 콘솔창에 찍어보자,정확히 9시간 차이가 난다.toISOString함수는 UTC시간을 기준으로 반환하기 때문인

velog.io

https://bbangaro.tistory.com/35

 

[JS] 배열 메소드 (reduce로 개수 구하기)

네엥.. 저번 포스팅에서 약속한대로 이번엔 reduce로 배열 객체 조작하는 법을 들고 왔습니다.. 동물칭긔들이 다루는 언어별 개수를 구해봅시다 reduce로 개수 구하기 let developers = [ {name:'cat', language

bbangaro.tistory.com

https://github.com/jquense/react-big-calendar/issues/1721 

 

Is it possible to get the selected date from the calendar in onSelectEvent callback function? · Issue #1721 · jquense/react-bi

Currently, the onSelectEvent function will return the event details. I would like to know that is there any possibilities to get the date of the calendar cell in onSelectEvent function. I know that...

github.com

728x90