3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

react-date-rangeでendDate選択時にのみアクションを発行する

Posted at

はじめに

react-date-rangeはカレンダーのUIから日付を選択できるライブラリ。
https://github.com/hypeserver/react-date-range

基本的な使い方

基本的な使い方はとてもシンプル

         <DateRange
              onRangeFocusChange={onSelectPeriod} // 後述
              onChange={(range) => postDate(range)} // 日付をクリック等で指定した際に発火
              moveRangeOnFirstSelection={false} // trueにするとクリックした日に範囲が限定される。false時はstartとendを指定した際に範囲が決定される
              months={2} // defaultで一画面上に表示される月の数
              ranges={[
                {
                  startDate: Date型の値,
                  endDate: Date型の値,
                  key: "selection" // 後述
                }
              ]} // ここに指定したstartとendが選択中の期間として設定される。
              direction="horizontal" // 縦か横か
              locale={jaLocale} // 言語設定
              dateDisplayFormat={"yyyy/MM/dd"} // 日付表示のフォーマット
              monthDisplayFormat={"yyyy年MMM"} // 月表示のフォーマット
              maxDate={endOfToday()} // 指定できる最大未来
              minDate={new Date(2000, 1, 1)} // 指定できる最古過去
            />

まじこれだけ。これ以外にもたくさんパラメータある。詳細はこちら

endDate選択時のみにアクションを発行する

onChange及びその他のonChange系列のアクション(onRangeFocusChangeも含む)の発火タイミングは日付をクリック等で指定したタイミングになっている。
すなわち、startとendを日付のクリックで決めると、2回onChangeが走る。
これだと単純にonChangeでサーバーにリクエストを送ってデータをfetchする場合、無駄なリクエストがstartのみを選択した瞬間に発生してしまう。だが、onChangeにはstartだけの選択なのか、endを選択したのかを示すようなパラメータが存在していない。

その情報はonRangeFocusChangeの引数に入っている。react-date-rangeはそれを[0, 0]または[0, 1]で表現している。
[0, 0]はstart/end両方を指定した時、[0, 1]はstartのみを指定したときである。

この情報をreduxやlocal stateで管理してその値を参照して、リクエストをサーバーに飛ばすか飛ばさないかを決めればいい。
しかし、onRangeFocusChangeの引数はこの[0, 1]とかの情報のみで、選択した日時の情報はない。
なので現状onChangeとonRangeFocusChangeを組み合わせる必要がある。
ローカルstateでやるならこんな感じかと。

const [isPeriodSelectionFinished, setIsPeriodSelectionFinished] = useState(true);

useEffect(() => {
 if (isPeriodSelectionFinished) {
  // post処理
 }
})

return (
           <DateRange
              onRangeFocusChange={(props) => setIsPeriodFinished(_.isEqual(props, [0,0]))}
              onChange={(range) => postDate(range)} // 日付をクリック等で指定した際に発火
              moveRangeOnFirstSelection={false} // trueにするとクリックした日に範囲が限定される。false時はstartとendを指定した際に範囲が決定される
              months={2} // defaultで一画面上に表示される月の数
              ranges={[
                {
                  startDate: Date型の値,
                  endDate: Date型の値,
                  key: "selection"
                }
              ]} // ここに指定したstartとendが選択中の期間として設定される。
              direction="horizontal" // 縦か横か
              locale={jaLocale} // 言語設定
              dateDisplayFormat={"yyyy/MM/dd"} // 日付表示のフォーマット
              monthDisplayFormat={"yyyy年MMM"} // 月表示のフォーマット
              maxDate={endOfToday()} // 指定できる最大未来
              minDate={new Date(2000, 1, 1)} // 指定できる最古過去
            />
)

いやユースケース的にend決定時に発火するonEndChange的なやつ作れ。
せめてonRangeFocusChangeの情報とonChangeの情報をどっちかに寄せて、どっちか使えば済むようにはしといてほしかったよね。
参考:https://github.com/hypeserver/react-date-range/issues/400

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?