React-TS-Calendar (Without Library)

Seuling·2022년 8월 2일
0

프로젝트

목록 보기
1/7
post-thumbnail

<Main/>

const Main = (props: Props) => {
  let DATE = new Date();
  const YEAR = DATE.getFullYear();
  const MONTH = DATE.getMonth() + 1;

  const [month, setMonth] = React.useState(MONTH);
  const [year, setYear] = React.useState(YEAR);

  const [today, setToday] = useState(0);

  const handleChangePrevButton = () => {
    const currentDate = new Date(`${year}-${month}`);
    currentDate.setMonth(currentDate.getMonth() - 1);
    setYear(currentDate.getFullYear());
    setMonth(currentDate.getMonth() + 1);
  };
  const handleChangeNextButton = () => {
    const currentDate = new Date(`${year}-${month}`);
    currentDate.setMonth(currentDate.getMonth() + 1);
    setYear(currentDate.getFullYear());
    setMonth(currentDate.getMonth() + 1);
  };

  return (
    <div>
      <Head
        year={year}
        month={month}
        handleChangePrevButton={handleChangePrevButton}
        handleChangeNextButton={handleChangeNextButton}
      />
      <BodyContainer>
        <Body today={today} month={month} year={year} />

        <Body today={today} month={month + 1} year={year} />
      </BodyContainer>
    </div>
  );
};

export default Main;

const BodyContainer = styled.div`
  display: flex;
`;

handleChangePrevButton : '<' 클릭

 const handleChangePrevButton = () => {
    const currentDate = new Date(`${year}-${month}`);
    currentDate.setMonth(currentDate.getMonth() - 1);
    setYear(currentDate.getFullYear());
    setMonth(currentDate.getMonth() + 1);
  };
  • 클릭한 시점에서의 Date를 구해야한다.
  • props로 받은 year 와 month를 기반으로 new Date()생성
  • Date()객체 내 setMonth 함수를 이용하여 currentDate의 Month를 set 해주기 -> 여기서 -1을 해주는 이유는 이전 버튼이니 이전 달인 -1
  • 그럼 새롭게 setMonth가 된 currentDate값을 setYear, setMonth에 넣어주기. 단 Date객체 로 되어있으니 여기서 Year, Month를 각각 해줘야함.
  • Month는 0월 부터이니 +1 해줌

<Head/>

const Head = (props: Props) => {
  const { year, month, handleChangePrevButton, handleChangeNextButton } = props;
  const nextDate = new Date(`${year}-${month}`);
  nextDate.setMonth(nextDate.getMonth() + 1);

  return (
    <HeadContainer>
      <form
        onSubmit={(e) => {
          e.preventDefault();
        }}
      >
        <ButtonContainer>
          <Button onClick={handleChangePrevButton}>&lt;</Button>
          <HeadTextContainer>
            <HeadText>
              {year}{month}</HeadText>
            <HeadText>
              {nextDate.getFullYear()}{nextDate.getMonth() + 1}</HeadText>
          </HeadTextContainer>
          <Button onClick={handleChangeNextButton}>&gt;</Button>
        </ButtonContainer>
      </form>
    </HeadContainer>
  );
};

export default Head;
  • nextDate를 만들어준 이유는 오른쪽에 새로운 달을 보여줘야하는데, 거기서의 month값을 조정해줘야하니 새롭게 Date()객체를 만들어서 getFullYear,getMonth 로 생성
  • form에 onSubmit이 default값이 있어서 버튼 클릭 시 새로고침되는 이슈 발생 -> e.preventDefault(); 로 해결

<Body/>

const Body = ({ today, month, year }: Props) => {
  const [totalDate, setTotalDate] = React.useState<number[]>([]);
  const currentMonthFirstDate = totalDate.indexOf(1);

  const nextMonthFirstDate = totalDate.indexOf(1, 7);
  const findToday = totalDate.indexOf(today);
  const currentMonth = new Date().getMonth() + 1;

  const changeDate = (month: number): number[] => {
    // 이전날짜
    let PreviousLastDate = new Date(year, month - 1, 0).getDate();
    let PreviousLastDay = new Date(year, month - 1, 0).getDay();
    //다음 날짜
    const NextDate = new Date(year, month, 0).getDate();
    const NextDay = new Date(year, month, 0).getDay();

    //이전날짜 생성
    let PVLD = [];
    //6==토요일 즉, 토요일이 아니면,
    //이전달의 마지막 요일
    // console.log(PreviousLastDay + 1);
    if (PreviousLastDay !== 6) {
      for (let i = 0; i < PreviousLastDay + 1; i++) {
        //unshift() 메서드는 새로운 요소를 배열의 맨 앞쪽에 추가하고, 새로운 길이를 반환합니다.
        PVLD.unshift(PreviousLastDate - i);
      }
    }
    //다음 요일 생성
    let TLD = [];
    for (let i = 1; i < 7 - NextDay; i++) {
      if (i === 0) {
        return TLD;
      }
      TLD.push(i);
    }
    //현재 날짜
    let TD = Array.from(Array.from(Array(NextDate + 1)).keys()).slice(1);
    // console.log(PVLD.concat(TD, TLD));
    //PVLD = 이전달의 남은날짜 + 이번달의 날짜 + 다음달의 올 날짜
    return PVLD.concat(TD, TLD);
  };

  useEffect(() => {
    setTotalDate(changeDate(month));
  }, [month]);
  const DAY = ["일", "월", "화", "수", "목", "금", "토"];

  return (
    <Container>
      <BodyContentContainer>
        <Days>
          {DAY.map((elm, idx) => {
            return <div key={idx}>{elm}</div>;
          })}
        </Days>

        {totalDate.map((date, index) => (
          <Dates
            key={index}
            index={index}
            currentMonthFirstDate={currentMonthFirstDate}
            nextMonthFirstDate={nextMonthFirstDate}
            elm={date}
            findToday={findToday === index && month === currentMonth}
            month={month}
            year={year}
          ></Dates>
        ))}
      </BodyContentContainer>
    </Container>
  );
};

export default Body;

<Dates/>


const Dates = ({
  index,
  currentMonthFirstDate,
  nextMonthFirstDate,
  elm,
  findToday,
  month,
  year,
}: Props) => {
  const DAY = ["일", "월", "화", "수", "목", "금", "토"];

  return (
    <DatesContainer>
      <DateNum
        index={index}
        currentMonthFirstDate={currentMonthFirstDate}
        nextMonthFirstDate={nextMonthFirstDate}
        findToday={findToday}
      >
        <TodayCSS findToday={findToday}>{elm}</TodayCSS>
      </DateNum>
    </DatesContainer>
  );
};

export default Dates;
profile
프론트엔드 개발자 항상 뭘 하고있는 슬링

0개의 댓글