[운동기록앱 - 달력앱] 3~4일차 기록

KwakKwakKwak·2022년 7월 16일
0

토이프로젝트

목록 보기
4/10
post-thumbnail

오늘은 어제 기록과 합친 이틀 짜리 기록이다. 어제도 코딩하긴 했는데 저녁에 한달 만에 축구동아리 풋살매치가 잡히는 바람에 신나게 차 몰고 가서 2시간 내내 뛰고 왔다. 경기 없는 동안 거의 매일 트레드밀 + 수영으로 체력 훈련을 해서 회복 속도는 빨랐는데 아무래도 실전에서의 폭발적인 가속 이후 근육이 털리는 문제는 평소 혼자 운동하는걸로는 해결하기 어렵더라. 그래도 운동을 열심히 해놓은 보람이랄까, 선배들에게 이름 콕 찍어 언급되면서까지 많이 좋아졌다고 칭찬도 듣고 3골 2어시를 기록하며 1인분까지 할 수 있었던게 참 보람찼다. 축구 너무 재밌고 좋다... 니가 무슨 손흥민이냐 하고 손가락질 하면 나도 할 말은 없다만 내 인생에서 축구를 금지시키면 더 이상 살 이유가 없을 정도로 필수적인 요소다.

여담이 길어지지만 내가 항상 마음 속에 새기는 것들 중 하나가 바로 '체덕지'이다. '바르고 건강한 몸과 체력에서 건강한 정신과 지혜가 깃든다'라는 교육관이다. 우리는 여지껏 학창시절 내내 '지덕>>>>>...>>>체'의 우선순위로 교육을 받아왔고, 그 '지' 마저도 사실은 지혜로움의 지가 아닌 암기력을 보기좋게 포장한 껍데기에 불과했다. 대학생이 되고 운동을 본격적으로 시작한 뒤부터 체육이 얼마나 평소 삶의 질을 업그레이드 시켜주는지 몸소 체감하면서 동시에 진짜 어렸을 때부터 운동과 가까워지지 못하게 한 이 한국 사회를 원망하게 됐다. 아무튼... 이 글을 보는 사람이 있다면 운동은 열심히 하자. 운동 좋아해서 손해보는거 진짜 1도 없다. 잡소리 끝!


이전 글에서 참고한 벨로그 코드들을 내 입맛대로 다시 해석하면서 아래와 같이 코드를 짰다.

import React from "react";
import { useState, useEffect } from "react";
import styled from "styled-components";

const CalendarData = ({ now, isFullSize }) => {
  const nowDay = now.getDay();
  const nowDate = now.getDate(); // 날짜
  const nowMonth = now.getMonth() + 1;
  const nowYear = now.getFullYear();

  const [today, setToday] = useState(nowDay);
  const [month, setMonth] = useState(nowMonth);
  const [year, setYear] = useState(nowYear);

  const lastDateOfThisMonth = new Date(
    now.getFullYear(),
    now.getMonth() + 1,
    0
  ).getDate();
  const lastDayOfThisMonth = new Date(
    now.getFullYear(),
    now.getMonth() + 1,
    0
  ).getDay();

  const lastDateOfLastMonth = new Date(
    now.getFullYear(),
    now.getMonth(),
    0
  ).getDate();
  const lastDayOfLastMonth = new Date(
    now.getFullYear(),
    now.getMonth(),
    0
  ).getDay();
  // now.getMonth() + 1, 0 -> 다음 달 1일에서 하루 전 = 이번 달 마지막 날짜

  // 페이지에 비춰질 날짜 배열 만들기 함수
  const changeDate = (month) => {
    // 이번 달 모든 날짜 배열
    let daysOfThisMonth = [];
    daysOfThisMonth = [...Array(lastDateOfThisMonth + 1).keys()].slice(1);

    // 저번 달 날짜 배열
    let daysOfLastMonth = [];
    if (lastDayOfLastMonth !== 6) {
      for (let i = 0; i < lastDayOfLastMonth + 1; i++) {
        daysOfLastMonth.unshift(lastDateOfLastMonth - i);
      }
    }

    // 다음 달 날짜 배열
    let daysOfNextMonth = [];
    for (let i = 1; i < 7 - lastDayOfThisMonth; i++) {
      if (i === 0) {
        return daysOfNextMonth;
      }
      daysOfNextMonth.push(i);
    }

    const final = daysOfLastMonth.concat(daysOfThisMonth, daysOfNextMonth);
    const result = [];
    for (let i = 0; i < final.length; i += 7) {
      result.push(final.slice(i, i + 7));
    }
    return result;
  };

  const [totalDate, setTotalDate] = useState(changeDate(month));

  useEffect(() => {
    setTotalDate(changeDate(month));
    console.log("month changed", changeDate(month));
  }, [month]);

  const goToday = () => {
    setMonth(nowMonth);
    setToday(nowDay);
  };

  let arrIndex;

  return (
    <>
      {isFullSize
        ? totalDate.map((value, index) => <div key={index}>{value}</div>)
        : totalDate.forEach((arr) => {
            if (arr.indexOf(nowDate) !== -1) {
              arrIndex = totalDate.indexOf(arr);
              console.log(`arrIndex:${arrIndex}`);
            }
          })}
      <div>{totalDate[arrIndex]}</div>
    </>
  );
};

export default CalendarData;

기본적으로 Date()함수를 활용해서 오늘과 이번 달 시작/마지막 날짜를 뽑아놓고 - 달력에 보여지는 모든 날짜들을 배열로 뽑은 다음 조건에 따라 알맞은 결과값을 반환하도록 짰다.

특히 달력 날짜 배열을 isFullSize(boolean) 값에 따라 전체 배열을 반환하거나 오늘 날짜가 포함된 이번 주 배열만 반환하도록 코드를 짰다. 그러나 처음엔 아래와 같은 코드였는데

return (
    <>
      {isFullSize
        ? totalDate.map((value, index) => <div key={index}>{value}</div>)
        : totalDate.forEach((arr) => {
            if (arr.indexOf(nowDate) !== -1) {
              <div>{arr}</div>;
            } // arr는 잘 뽑히는데 왜 출력이 안되는 것..?
          })}
    </>
  );

위와 같이 코드를 짠 뒤 forEach문 안의 arr 값이 콘솔에 제대로 찍히는 것까지 보고도 내 앱에는 아무 것도 출력되지 않아서 뭐가 문젠지 한 시간 동안이나 끙끙댔다.


그래서 친구한테 물어보니까 단번에 해결되더라 내 한 시간 어디갔어!
map 함수는 새로운 배열을 반환하지만 forEach 함수는 반환 값이 없다는 사실을 알게 되었다. 아래는 수정 완료한 코드.

let arrIndex;
return (
    <>
      {isFullSize
        ? totalDate.map((value, index) => <div key={index}>{value}</div>)
        : totalDate.forEach((arr) => {
            if (arr.indexOf(nowDate) !== -1) {
              arrIndex = totalDate.indexOf(arr);
              console.log(`arrIndex:${arrIndex}`);
            }
          })}
      <div>{totalDate[arrIndex]}</div>
    </>
  );

이번 주의 index를 forEach문으로 새 변수에 할당해놓고 totalDate 배열 중 이번 주 배열만 출력하도록 변경했다. map함수로 한꺼번에 삼항연산자 여러 개 써서 좀 더 깔끔하게 구현해보려 했는데 현재로서는 이게 최선이다.,

그래서 아래는 결과물 스샷이다.


왼쪽은 isFullSize가 false일 때, 오른쪽은 true일 때 모습. styled components로 꾸며야하겠지만 우선 원하는 대로 숫자가 뽑히니 다행이다.


원래 이 달력 컴포넌트는 내 프로젝트의 기능 중 단 하나에 불과했는데, 만들면서 보니까 달력 앱의 기능을 제대로 수행하게끔 코드를 짜는 것 자체가 하나의 프로젝트가 되어야할 것 같다는 생각이 들었다. 그래서 대충 껍데기만 만들어놓지 않고 달력 앱 자체를 하나의 소프로젝트로 보고 디테일하게 구현하려 마음먹었다.

기존의 달력 앱처럼 1일부터 말일까지 보이고 이전/이후 달로 넘길 수 있는 것은 물론이오, 달력 데이터를 위 결과물처럼 일주일짜리로 떼어 올 수 있도록 하는 유동성도 확보하고 싶다. 내 성격상 한 번 하면 그래도 제대로 끝을 봐야 직성이 풀리기 때문에 최대한 깔쌈하게 만들 예정이다. 배포까지 해보자! 수고했다👍

0개의 댓글