🐜 Mineアプリケーションプロジェクト-カレンダーページ(2)


🐜 Mineアプリケーションプロジェクト-カレンダーページ(2)



第1編では、カレンダーを描くために悩んでいる部分と、どのようにカレンダーを描くかについて書いてみました.
2編では,静的に定義されたデータを動的に変更する方法と,移動機能とデータパターンの問題を発見してカレンダーを再描画する方法について述べる.

📓 月移動機能の追加


月移動機能の作成



前編では、7月のカレンダーを作成しました.
カレンダーロジックがうまくいけば8月から9月にかけてもカレンダーを描きましょうか?
今回は、月シフト機能を追加して、月シフトでもカレンダーをうまく描く機能を作成します.

[1]MonthSweepperContainerコンポーネントの作成


月移動機能を作成するには、まず構造を決定します.
編んだ和弦が落ちないように命名への苦悩
今回も何度も悩んだ末に『MonthSweeper』が誕生しました
そして思いがけない困難にぶつかった.
<、>などの特殊文字をどのように表すかという問題が発生しました.
だからまたグーグルのチャンスを使いました:)

必要な情報を得た

以下のように作成します.
import { useSelector } from 'react-redux';

export default function MonthSwiperContainer() {
  const { year, month } = useSelector((state) => ({
    year: state.year,
    month: state.month,
  }));

  return (
    <>
      <div>
        <button
          type="button"
        >
         &lt;
        </button>
      </div>
      <div>
        <div>{year}</div>
        <div>{month}</div>
      </div>    
      <div>
        <button
          type="button"
        >
         &gt;
        </button>
      </div>
    </>
  );
}

[2]アクションクリエイターの作成


今から動くアクション映画を作りましょう

先月どう表現したか考えてみよう
基準が2021年2月なら、先月は2021年1月だったはずです.
month - 1
基準が2021年1月なら2020年12月になるはずです.
year - 1 & month + 11
このように考える論理をコードに適用すると,以下のようになる.
  setPreviousMonth(state, { payload: { month } }) {
      if (month === 1) {
        return {
          ...state,
          year: state.year - 1,
          month: state.month + 11,
        };
      }
      return {
        ...state,
        month: state.month - 1,
      };
    },
同じ来月はどう表現しますか?

基準が2021年11月なら、先月は2021年12月だったはずです.
month + 1
基準は2021年12月だと2022年1月だと思います
year + 1 & month - 11
同様に、次のようにコードを記述するだけでいいです.
    setNextMonth(state, { payload: { month } }) {
      if (month === 12) {
        return {
          ...state,
          year: state.year + 1,
          month: state.month - 11,
        };
      }
      return {
        ...state,
        month: state.month + 1,
      };
    },

[3]ボタンクリックイベントを書きましょう。


上でアクションシーンを作りましたアクションシーンを確認してくれませんか?<button>ラベルにonClickアクティビティと書いて
ボタンをクリックすると動きが出てきますよね?
動作をディスパッチで伝える
monthは1月から12月までなので、次のコードのように条件を追加します.
import { useDispatch, useSelector } from 'react-redux';

import {
  setPreviousMonth,
  setNextMonth,
} from '../slice';

export default function MonthSwiperContainer() {
  const dispatch = useDispatch();

  const { year, month } = useSelector((state) => ({
    year: state.year,
    month: state.month,
  }));

  // month : 1 ~ 12
  // month에 대한 조건을 추가해주겠습니다.
  const handleChangePreviousMonth = () => {
    if (month > 0) {
      dispatch(setPreviousMonth({ month }));
    }
  };

    // 마찬가지로 month에 대한 조건을 추가해주겠습니다.
  const handleChangeNextMonth = () => {
    if (month < 13) {
      dispatch(setNextMonth({ month }));
    }
  };

  return (
    <>
      <div>
        <button
          type="button"
          onClick={handleChangePreviousMonth}
        >
         &lt;
        </button>
      </div>
      <div>
        <div>{year}</div>
        <div>{month}</div>
      </div>    
      <div>
        <button
          type="button"
          onClick={handleChangeNextMonth}
        >
         &gt;
        </button>
      </div>
    </>
  );
}
また、次の機能も備えています.

📓 最初の画面を該当する月に自動的にレンダリングしてください


カレンダーを描くときに自動的に現れる月を描きましょう


たとえば、2022年10月5日が今日の場合、2022年10月カレンダーのレンダリング機能を作成します.

[1]静的に定義されたデータを動的に作成する


データは2021年7月と定義されているため、2021年8月と2022年7月とを問わず、2021年7月のカレンダーが初めて画面に表示されます.

データ定義を変更することをお勧めします.
Dateオブジェクトを使用して現在の日付を定義し、現在の年と現在の月を定義します.
静的定義のデータを動的に作成するには、次の変更を行います.
今日は2021年8月23日なので、8月カレンダーは初めて画面で描きます.
import { createSlice } from '@reduxjs/toolkit';

const today = new Date();

const { actions, reducer } = createSlice({
  name: 'application',
  initialState: {
    year: today.getFullYear(),
    month: today.getMonth() + 1,
  },
  reducers: {},
});

export const {} = actions;

export default reducer;

📓 コードを再設計してデータ・モードを再定義し、カレンダーを描画します。


以前に作成したカレンダーを描くコードは日付値のみです.( 前のリンク )
// ... 생략

カレンダーを描けばいいと思ったので近づいたので、日付値だけを見つけて配列に入れました.
しかし、他の機能を作成しようとすると、いくつかの問題が発生し、データ・モードを再定義します.
日付は1日から30日または1日から31日または1日から28日まで数字で表示されます.
ただし、これらの日付値は7月1日か8月1日かは区別されません.
そこで,データパターンを再定義し,さらなる再パッケージを行う.
次に示すように、必要なデータを再定義します.
1"lastOfPreviousMonth(先月の最後の年、月、日、日)
2▼lastofThisMonth(今月最後の年、月、日、日)
3」「StartOfNextMonth(来月の開始日は年、月、日、日)

以前に作成されたコードは可読性に欠けており、コードを表示するときにコメントがない人がいる場合は、理解するのに時間がかかる場合があります.
だからそれを関数にして可読性を高めます

✔getPreviousDates関数



✔getThisDates関数



✔getNextDates関数



✔GetWeeks関数



下の図のようにコードを変更すればいいです.
export default function CalendarMonth({ year, month  }) {
 // 생략
  ... 
  
  return getWeeks().map((week) => (
    <div
      key={week}
    >
      {
        week.map((date) => (
          <div
            key={date}
          >
            {date}
          </div>
        ))
      }
    </div>
  ));
}

次の追加機能について説明します。


土曜日、日曜日は色を区別します
今日は日付を表示
表示されるカレンダーに先月と来月の日付を表示します.

📋 さらなる解決が必要な問題について...


①不変性を崩さず、新しい配列に変える必要があります!


非表示コード項目の実行時に受信したフィードバック

②今日は週末の色が変わらないことに気づいた


③現在の月の開始日は日曜日で、先月のデータは不要


下図のように2021年8月のカレンダーに問題があることに気づきました.

さらに解決すべき問題については、逐次漸進的に解決し、ブログに整理します.