LoginSignup
2
3

More than 3 years have passed since last update.

ReactでDatePicker(react-datepicker)+ reactstrap + formikを使う

Last updated at Posted at 2019-12-02

やりたいこと

datepickerを使うと、そこだけCSSが適用されなかったり、独自バリデーションとなるのを、ReactStrapで見た目を整え、Formikでバリデーションしたい。

完成

以下のような感じを目指す。

スクリーンショット 2019-12-02 13.09.29.png

準備

作業場所と必要なモジュールをインストール。

create-react-app datepicker
cd datepicker
yarn add react-datepicker
yarn add bootstrap reactstrap moment formik yup

npm install --save bootstrap reactstrap moment formik yup

実装

ポイントはreact-datepickerのcustomInputでReactstrapのInputを指定しているところ。
dateのバリデーションはとりあえず当月以外が指定されたらエラーが出るようにしている。

App.js
import React from 'react';
import './App.css';
import { Form, FormGroup, Label, Input, FormFeedback, Button } from 'reactstrap';
import { Formik } from 'formik';
import * as Yup from 'yup';
import moment from 'moment';

//react-datepicker
import DatePicker, { registerLocale } from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
//for locale ja
import ja from 'date-fns/locale/ja';
registerLocale('ja', ja);


class App extends React.Component {

    handleOnSubmit = (values) => {
        alert(JSON.stringify(values));
    }

    render() {
        return (
            <React.Fragment>
                <div className="container">
                    <Formik
                        initialValues={{ email: '', startDate: moment(new Date()).format('YYYY/MM/DD') }}
                        onSubmit={this.handleOnSubmit}
                        validationSchema={Yup.object().shape({
                            email: Yup.string().email().required(),
                            startDate: Yup.string().required().test('checkDate', '当月を指定して下さい。', (picked) => {
                                const pickedMonth = moment(new Date(picked)).month() + 1;
                                const thisMonth = moment(new Date()).month() + 1;
                                if (pickedMonth === thisMonth) {
                                    return true;
                                } else {
                                    return false;
                                }
                            }),
                        })}
                    >
                        {
                            ({ handleSubmit, handleChange, handleBlur, values, errors, touched, setFieldValue }) => (
                                <Form onSubmit={handleSubmit} className="col-8 my-5">
                                    <FormGroup >
                                        <Label for="email">Email</Label>
                                        <Input
                                            type="email"
                                            name="email"
                                            id="email"
                                            onChange={handleChange}
                                            onBlur={handleBlur}
                                            invalid={Boolean(touched.email && errors.email)}
                                        />
                                        <FormFeedback>
                                            {errors.email}
                                        </FormFeedback>
                                    </FormGroup>
                                    <FormGroup>
                                        <legend className="col-form-label">開始日時</legend>
                                        <DatePicker
                                            locale="ja"
                                            name="startDate"
                                            id="startDate"
                                            value={values.startDate}
                                            dateFormat="YYYY/MM/DD"
                                            customInput={<Input invalid={Boolean(errors.startDate)} />}
                                            onChange={date => setFieldValue("startDate", moment(date).format('YYYY/MM/DD'))}
                                        />
                                        <p className="text-danger small">{errors.startDate}</p>
                                    </FormGroup>
                                    <div className="my-3">
                                        <Button type="submit">送信</Button>
                                    </div>
                                </Form>
                            )
                        }
                    </Formik>
                </div>
            </React.Fragment>
        );
    }
}

export default App;

2
3
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
2
3