Reactで日付入力にカレンダー（DatePicker）を使う ※年をプルダウンで指定して元号も表示する

## 概要

Reactで日付入力にカレンダー（DatePicker）を使う。

## 実装

[React Datepicker](https://reactdatepicker.com/#example-inject-specific-times)を使うと楽。

### サンプル

※
年：プルダウン指定（元号付き）
月：プルダウン指定
`<InputeDate />` で。

```jsx
import getMonth from 'date-fns/getMonth';
import getYear from 'date-fns/getYear';
import ja from 'date-fns/locale/ja';
import React from "react";
import DatePicker, { registerLocale } from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

// jaのロケールの設定が週頭が月曜始まりになっているので日曜始まりにする
ja.options.weekStartsOn = 0;
// ReactDatepickerのロケール登録
registerLocale('ja', ja);

class InputDate extends React.Component {
    state = {
        startDate: null
    };

    handleChange = date => {
        this.setState({
            startDate: date
        });
    };

    eraHandler = yearNow => {

        const generate = (era, startYear) => {
            let yearDsp = yearNow - startYear + 1;
            if (yearDsp === 1) {
                yearDsp = "元";
            } else {
                yearDsp = ('00' + yearDsp).slice(-2);
            }
            return `${era}${yearDsp}年`;
        };

        if (yearNow >= 2019) {
            return generate('令和', 2019);
        }

        if (yearNow >= 1989) {
            return generate('平成', 1989);
        }

        if (yearNow >= 1926) {
            return generate('昭和', 1926);
        }

        if (yearNow >= 1912) {
            return generate('大正', 1912);
        }
    }

    render() {
        var startYear = 1912; // カレンダーに表示する最初の西暦（大正元年となる1912を指定）
        var futureListUp = 5; // カレンダーに表示する未来の年数
        var years = Array.from({ length: getYear(new Date()) - startYear + futureListUp }, (v, k) => k + startYear).reverse();
        const months = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];

        return (
            <React.Fragment>
                <DatePicker
                    locale='ja'
                    selected={this.state.startDate}
                    onChange={this.handleChange}
                    placeholderText="日付を選択してください"
                    dateFormat="yyyy/MM/dd"
                    isClearable
                    showMonthDropdown
                    showYearDropdown
                    todayButton="今日"
                    dropdownMode="select"
                    // カレンダーのヘッダ部分をカスタマイズする
                    renderCustomHeader={({
                        date,
                        changeYear,
                        changeMonth,
                        decreaseMonth,
                        increaseMonth,
                        prevMonthButtonDisabled,
                        nextMonthButtonDisabled
                    }) => {
                        return (
                            <div
                                style={{ margin: 10, display: "flex", justifyContent: "center" }}>

                                {/* 前月ボタン */}
                                <button onClick={decreaseMonth} disabled={prevMonthButtonDisabled}>{"<"}</button>

                                {/* 年の部分 */}
                                <select value={getYear(date)} onChange={({ target: { value } }) => changeYear(value)} >
                                    {years.map((option) => (
                                        // eraHandler()で年のプルダウンに元号を付ける
                                        <option key={option} value={option}>{option}年（{this.eraHandler(option)}）</option>
                                    ))}
                                </select>

                                {/* 月の部分 */}
                                <select value={months[getMonth(date)]} onChange={({ target: { value } }) => changeMonth(months.indexOf(value))} >
                                    {months.map(option => (
                                        <option key={option} value={option}> {option}月 </option>
                                    ))}
                                </select>

                                {/* 次月ボタン */}
                                <button onClick={increaseMonth} disabled={nextMonthButtonDisabled}>{">"}</button>
                            </div>
                        );
                    }
                    }
                />
            </React.Fragment>
        );
    }
}
```
## 参考

* [公式 GitHub](https://github.com/Hacker0x01/react-datepicker)
* [公式 使い方 ※色んなパターンが紹介されているので必見](https://reactdatepicker.com/#example-inject-specific-times)
* [Reactでカレンダーを使う](https://qiita.com/Hitomi_Nagano/items/c6f0e84f1c892c6e69b3)
* [ロケール一覧](https://date-fns.org/v2.0.0-alpha.18/docs/I18n)
* [jaロケールのgitHub ※index.jsに設定がある](https://github.com/date-fns/date-fns/tree/master/src/locale/ja)