혼자 적어보는 노트

[React] 라이브러리 없이 캘린더 만들어 보기 본문

React

[React] 라이브러리 없이 캘린더 만들어 보기

jinist 2022. 1. 10. 04:40

라이브러리 없이 캘린더 만들기에 도전 해보기로 했다.

 

여기저기 블로그를 돌아다니며

javascript로 만드는 방법들을 참고해서 react에 적용 해보았다.

 

 

  const [thisCalender, setThisCalender] = useState(null);
  const today = new Date();
  const thisYear = today.getFullYear();
  const thisMonth = today.getMonth();

상단에 위와 같이 날짜정보를 담을 state, today, thisYear, thisMonth를 만들어준다.

 

  const calenderMaker = () => {
    const prevLast = new Date(thisYear, thisMonth, 0);
    // 지난 달의 마지막 날짜 정보
    const thisLast = new Date(thisYear, thisMonth + 1, 0);
    // 이번 달의 마지막 날짜 정보

    const prevLastDate = prevLast.getDate();
    // 지난 달의 마지막 날짜
    const prevLastDay = prevLast.getDay();
    // 지난 달의 마지막 요일

    const thisLastDate = thisLast.getDate(); // 이번 달의 마지막 날짜
    const thisLastDay = thisLast.getDay(); // 이번 달의 마지막 요일

    const prevDates = [];
    const thisDates = [...Array(thisLastDate + 1).keys()].slice(1);
    //이번 달의 마지막 날짜의 갯수 만큼 빈 배열을 만들어주고
    // keys()를 통해 배열의 길이에 맞게 0부터 숫자를 담아준다
    // keys()를 이용하여 만들면 0부터 시작하기 때문에 slice로 첫번째 값을 지워준다.
    
    const nextDates = [];

    if (prevLastDay !== 6) {
      for (let i = 0; i < prevLastDay+1; i++) {
        prevDates.unshift(prevLastDate - i);
      }
    }
    //지난 달의 마지막 요일이 토요일이 아니라면
    요일의 number만큼 지난달의 마지막 날짜부터 담아준다
    
    

    for (let i = 1; i < 7 - thisLastDay; i++) {
      nextDates.push(i);
    }
    // 일주일에서 이번달 마지막 요일의 number 만큼 빼주고
    다음 달의 날짜를 담아준다.
    
    setThisCalender({ prev: prevDates, thisDate: thisDates, next: nextDates });
  };
  
  useEffect(() => {
    calenderMaker();
  }, []);

 

gatMonth()로 받는 월에 대한 정보는 0~11까지의 숫자로 표시된다.

1월의 경우 0으로 표시되기 때문에 +1를 해주어야 알맞게 달을 구할 수 있다.

 

getDay()도 마찬가지로 0(일요일)부터 6 (토요일)까지 요일을 숫자로 전달 해 준다.

 

 

{thisCalender &&
  thisCalender?.prev.map((day, i) => (
    <div key={i} className="prev cell">
      {day}
    </div>
  ))}
{thisCalender &&
  thisCalender?.thisDate.map((day, i) => (
    <div key={i} className="date cell">
      {day}
    </div>
  ))}
{thisCalender &&
  thisCalender?.next.map((day, i) => (
    <div key={i} className="next cell">
      {day}
    </div>
  ))}

보기 편하게 하고 싶어서 thisCalender에는

prev, thisDate, next를 담아주고 일일히 뽑아주었다.

 

 

 

이전 달/ 다음달 이동

 

버튼 클릭 시 이전 달과 다음 달으로 이동할 수 있는 기능을 추가해보자.

  const [currentDate, setCurrentDate] = useState({
    date: new Date(),
    year: new Date().getFullYear(),
    month: new Date().getMonth(),
  });

currentDate라는 state를 만들어 주고

기존에 today, thisYear, thisMonth를 참조 했던 코드를 수정해주었다.

 

state에 date만 넣으려고 했지만 달력 상단에 year과 month를 표기해주기 위해

month와 year도 담아 주었다.

    const prevLast = new Date(currentDate.year, currentDate.month, 0);
    const thisLast = new Date(currentDate.year, currentDate.month + 1, 0);

 

  const clickPrev = () => {
    const time = currentDate.date.setMonth(currentDate.month - 1);
    // date를 setMonth를 이용하여 다시 설정해준 후 time값을 받는다
    const date = new Date(time);
    // 숫자로된 time값을 Date형식으로 변경해준다.
    setCurrentDate({ date, year: date.getFullYear(), month: date.getMonth() });
  };
  const clickNext = () => {
    const time = currentDate.date.setMonth(currentDate.month + 1);
    const date = new Date(time);
    setCurrentDate({ date, year: date.getFullYear(), month: date.getMonth() });
  };

  useEffect(() => {
    calenderMaker();
  }, [currentDate]); //currentDate가 변경될 때 마다 calenderMaker 실행

 

 

 

참고 : https://bigtop.tistory.com/66

 

 

Comments