Casual Developers Note

エンジニアやデザイナー向けの技術情報・英語学習情報・海外留学情報・海外旅行情報を提供中。世界を旅して人生を楽しもう。

  • ホーム
  • 技術 Tips & Tutorials
  • 技術塾
  • ライフハック
  • 海外留学
  • 英語学習
  • コラム
  • お問い合わせ
現在の場所:ホーム / アーカイブformik

2019年4月12日 By KD コメントを書く

FormikでReactのフォームを華麗に扱う方法

FormikでReactのフォームを華麗に扱う方法

Reactのフォーム用ライブラリ「Formik」でフォームを華麗に扱う方法を紹介します。

はじめに

Reactでフォームを扱う場合、ライブラリを使わないとソースコードが煩雑になってしまいます。React/Reduxの環境でポピュラーなフォーム用のライブラリといえば「Redux Form」ですが、Redux自体は必須というわけではなく、Reactのみでフロントエンドを構築する場合もあるため、Reduxを前提としたフォーム用ライブラリを使うと、React/Reduxで構築したアプリケーションをReactのみに書き直した場合などにコンポーネントの再利用性を低下させてしまいます。そこで、Reduxとは関係のないReactのフォーム用ライブラリとして「Formik」という選択肢が出てきます。

今回は、「Formik」を使って、Reactのフォームを扱う方法を紹介します。

Formikとは?

「Formik」とは、単独で利用可能なReactのフォーム用ライブラリです。

前提

以下の準備が完了している必要があります。

  • NodeJSがインストールされていること
  • create-react-appがインストールされていること

細かいバージョンは「環境」を参照してください。

FormikでReactのフォームを作成する

ベースを作る

まずは、Reactのプロジェクトを作成し、必要なパッケージをインストールします。

$ npx create-react-app formik-sample
$ cd formik-sample/
$ rm src/App.css
$ rm src/App.test.js
$ rm src/logo.svg
$ touch src/MyForm.js
$ yarn add formik yup bootstrap reactstrap
$ tree -aI 'node_modules|.git'
.
├── .gitignore
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── src
│   ├── App.js
│   ├── MyForm.js
│   ├── index.css
│   ├── index.js
│   └── serviceWorker.js
└── yarn.lock

フォームを実装する

入力チェック付きのフォームを実装しましょう。

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

index.css

body {
  text-align: center;
  font-size: 1.5rem;
  padding: 3%;
}

App.js

import React from 'react';
import MyForm from './MyForm';

const App = () => (
  <>
    <MyForm />
  </>
);

export default App;

MyForm.js

import React from 'react';
import {
Button,
Form,
FormGroup,
Label,
Input as ReactstrapInput,
FormFeedback,
} from 'reactstrap';
import { withFormik, ErrorMessage, Field } from 'formik';
import * as yup from 'yup';
const Input = ({ name, ...others }) => (
<Field
name={name}
render={({ field }) => <ReactstrapInput {...field} {...others} />}
/>
);
const ErrorFormFeedback = ({ name }) => (
<ErrorMessage
name={name}
component={({ children }) => <FormFeedback>{children}</FormFeedback>}
/>
);
const ErrorInnerMessage = ({ name }) => (
<ErrorMessage
name={name}
component={({ children }) => (
<span className="text-danger" style={{ fontSize: '1.2rem' }}>
{children}
</span>
)}
/>
);
const MyForm = ({
handleSubmit,
handleReset,
isSubmitting,
dirty,
errors,
touched,
}) => (
<div className="mx-auto col-8">
<h2>My Form</h2>
<Form className="text-left" onSubmit={handleSubmit}>
<FormGroup className="mb-2">
<Label for="myEmail">Email</Label>
<Input
type="email"
name="email"
id="myEmail"
placeholder="Enter email"
valid={dirty && !errors.email}
invalid={touched.email && !!errors.email}
/>
<ErrorFormFeedback name="email" />
</FormGroup>
<FormGroup className="mb-2">
<Label for="myUsername">Username</Label>
<Input
type="text"
name="username"
id="myUsername"
placeholder="Enter username"
valid={dirty && !errors.username}
invalid={touched.username && !!errors.username}
/>
<ErrorFormFeedback name="username" />
</FormGroup>
<FormGroup className="mb-2">
<Label for="myPassword">Password</Label>
<Input
type="password"
name="password"
id="myPassword"
placeholder="Enter password"
valid={dirty && !errors.password}
invalid={touched.password && !!errors.password}
/>
<ErrorFormFeedback name="password" />
</FormGroup>
<FormGroup className="mb-2" tag="fieldset">
<legend>Gender</legend>
<FormGroup inline check>
<Label check>
<Input type="radio" name="gender" value="male" />
male
</Label>
</FormGroup>
<FormGroup inline check>
<Label check>
<Input type="radio" name="gender" value="female" />
female
</Label>
</FormGroup>
<span className="ml-3">
<ErrorInnerMessage name="gender" />
</span>
</FormGroup>
<FormGroup check className="mb-2">
<Input type="checkbox" name="isAccepted" id="myCheck" />
<Label for="myCheck" check>
Accept
</Label>
<span className="ml-3">
<ErrorInnerMessage name="isAccepted" />
</span>
</FormGroup>
<div className="d-flex justify-content-center">
<span className="p-2">
<Button
type="button"
outline
color="secondary"
onClick={handleReset}
disabled={!dirty || isSubmitting}
>
Reset
</Button>
</span>
<span className="p-2">
<Button type="submit" outline color="primary" disabled={isSubmitting}>
Submit
</Button>
</span>
</div>
</Form>
</div>
);
const MyEnhancedForm = withFormik({
mapPropsToValues: () => ({
username: '',
email: '',
password: '',
gender: '',
isAccepted: false,
}),
handleSubmit: (values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 3000);
},
validationSchema: yup.object().shape({
email: yup
.string()
.email('Enter a correct email ')
.required('Enter an email'),
username: yup
.string()
.min(3, 'A username must contain more than 3 characters')
.required('Enter a username'),
password: yup
.string()
.min(8, 'A username must contain more than 8 characters')
.required('Enter a password'),
gender: yup
.string()
.oneOf(['male', 'female'])
.required('Check a gender'),
isAccepted: yup.boolean().oneOf([true], 'Must accept terms and conditions'),
}),
})(MyForm);
export default MyEnhancedForm;

Formikの実装方法は、Formikコンポーネントでそのままフォームを実装するシンプルな方法と、withFormikコンポーネントでフォームのコンポーネントをラップするHOC(higher-order component)の方法があります。今回は実際に使うことが多い後者のHOCの方法で実装しています。

動作確認

それでは、アプリケーションを起動し、フォームの入力チェックが正しく動くか確認しましょう。

$ yarn start

NewImage

入力チェックが正しく行われるか確認します。

NewImage

正しいデータが入力されたこを確認します。

NewImage

「Submit」ボタンをクリックして、入力したデータが表示されることを確認します。

NewImage

OKですね。

最後に

いかがでしたか?これでReduxに依存すること無く、「Formik」でReactのフォームを華麗に扱うことができるようになったのではないでしょうか。それでは。

環境

  • NodeJS: v11.13.0
  • create-react-app: 2.1.8
  • bootstrap: 4.3.1
  • reactstrap: 8.0.0
  • formik: 1.5.2
  • yup: 0.27.0

カテゴリ : 技術 Tips & Tutorials タグ : formik, react, yup

ブログ更新情報や海外の関連情報などを配信する無料メルマガ

Sponsored Links

About Author

KD

世界を旅し日本を愛するエンジニア。大学でコンピュータサイエンスの楽しさを学び、日本の大手IT企業で働く中で、新しい技術やスケールするビジネスが北米にある事に気づく。世界に挑戦するための最大の壁が英語であったため、フィリピン留学およびカナダ留学を経て英語を上達させた。現在は日本在住でエンジニアとして働きつつ、次の挑戦に備えて世界の動向を注視している。挑戦に終わりはない。このブログでは、エンジニアやデザイナー向けの技術情報から、海外に留学したい人向けの留学情報、海外に興味がある人向けの海外旅行情報など、有益な情報を提供しています。

https://casualdevelopers.com/

最近の投稿

  • 2020年JS周辺のバックエンド寄りの注目技術!ネクストNodeJSの「Deno」と分散型パッケージレジストリの「Entropic」の紹介

    2020年JS周辺のバックエンド寄りの注目技術!ネクストNodeJSの「Deno」と分散型パッケージレジストリの「Entropic」の紹介

    2020年1月13日
  • 今さら聞けないJavaによる関数型プログラミング入門 ~ラムダ式、ストリーム、関数型インターフェース~

    今さら聞けないJavaによる関数型プログラミング入門 ~ラムダ式、ストリーム、関数型インターフェース~

    2019年11月4日
  • ReactのためのEslintおよびPrettierの設定方法 ~Airbnb JavaScript Style Guideの適用~

    ReactのためのEslintおよびPrettierの設定方法 ~Airbnb JavaScript Style Guideの適用~

    2019年10月30日
  • BashからZshに移行する方法(Mac編)

    BashからZshに移行する方法(Mac編)

    2019年10月21日
  • Create React Appを使わないでゼロからReactの開発環境を構築する方法(Webpack/Docker編)

    Create React Appを使わないでゼロからReactの開発環境を構築する方法(Webpack/Docker編)

    2019年9月30日

カテゴリ

  • 技術 Tips & Tutorials (100)
  • 技術塾 (6)
  • ライフハック (26)
  • 海外留学 (12)
  • 英語学習 (3)
  • コラム (6)

アーカイブ

最高の学習のために

人気記事ランキング

  • MySQLで「ERROR 2003 (HY000): Can't connect to MySQL server」と怒られた時の対処法
    MySQLで「ERROR 2003 (HY000): Can't connect to MySQL server」と怒られた時の対処法
  • Expressで「Cannot set headers after they are sent to the client」と怒られた時の対処法
    Expressで「Cannot set headers after they are sent to the client」と怒られた時の対処法
  • SAKURAのメールボックスで独自ドメインのメールを設定し、Gmail経由で送受信する方法
    SAKURAのメールボックスで独自ドメインのメールを設定し、Gmail経由で送受信する方法
  • [tips][perl] Perlで文字コードをいい感じに処理する方法
    [tips][perl] Perlで文字コードをいい感じに処理する方法
  • 爆速でJenkinsをマスターしよう(GitHubアカウント統合編) ~ JenkinsのGitHub Organizationの設定方法 ~
    爆速でJenkinsをマスターしよう(GitHubアカウント統合編) ~ JenkinsのGitHub Organizationの設定方法 ~
  • Jupyter Notebookで「The kernel appears to have died. It will restart automatically.」というエラーが出た場合の原因と対処法
    Jupyter Notebookで「The kernel appears to have died. It will restart automatically.」というエラーが出た場合の原因と対処法
  • FacebookログインのJavascriptのSDKをサクッと試す方法
    FacebookログインのJavascriptのSDKをサクッと試す方法
  • SLF4JとLogbackによるJavaのロギング入門(SLF4J + Logback + Lombok)
    SLF4JとLogbackによるJavaのロギング入門(SLF4J + Logback + Lombok)
  • [tips][bat] バッチで明日の日付を計算する。
    [tips][bat] バッチで明日の日付を計算する。
  • PythonでWebスクレイピング入門(Scrapy+Selenium編)
    PythonでWebスクレイピング入門(Scrapy+Selenium編)

Bitcoin寄付 / BTC Donation

Bitcoinを寄付しよう

BTC
Select Payment Method
Personal Info

Donation Total: BTC 0.0010

このブログの運営のためにBitcoinでの寄付を募集しています。お気持ち程度の寄付を頂けると管理者の励みになります。

Bitcoin寄付について知りたい方はこちらの記事へ

ビットコイン取引ならここ

  • ホーム
  • 技術 Tips & Tutorials
  • 技術塾
  • ライフハック
  • 海外留学
  • 英語学習
  • コラム
  • サイトマップ
  • タグ一覧
  • プライバシーポリシー
  • お問い合わせ

Copyright © 2023 KD - Casual Developers Notes