React.jsだけで作る!バリデーション付きフォームの作り方!

React.jsだけで作る!バリデーション付きフォームの作り方!

– React!前回までは –

Reactという謎の単語を目にし、意気揚々と調査に乗り込む。
そこで見たものは英語と専門用語に溢れた参考記事の数々…。
そんな中、どうにか自力でプログラムの入り口「Hello!World!」の出力に半日かけてようやく成功し、その勢いでバリデーション付きフォームの作成にとりかかったのであった…。
前回の記事:React.jsって?初心者から始めるReact導入!

ということで今回はグッと実用レベルまで難易度を上げて、React.jsだけを使用したバリデーション付きフォームの作り方を解説します!

ちなみに今回ここまでたどり着くのに約20時間近くダラダラとかかってしまいました…。ぐぬぬ、侮れないぞReact.js。

Reactでの値の受け渡しpropsとstate

まずReactを使う上で決して避けては通れないプロパティがこのpropsstateです。
これらはどんな働きをしてくれるのかと言うと、どちらも設定した値を引数のように値を受け渡してくれます。
そして値の受け渡しは組み方によってajaxのようにリアルタイムで表示されている情報を更新してくれます。

自分なりに解釈したpropsとstateの特徴は以下の通り

  • props … コンポーネント間の値の受け渡しに使用。React内で静的な値を設定するといった使い方も。
  • state … 同一コンポーネント内で値の受け渡しに使用。外部からのアクションに応じて値を変化させたいときに。

propsとstateの解説については既にたくさんの参考記事が書かれています。
Reactを扱う上でかなり重要な要素ですが、詳細な解説をするとそれだけで記事が1つ出来てしまうほどなので、今回は作成過程で参考にさせて頂いた記事を紹介します。

参考にさせていただいた記事

今回作成したフォーム内でのpropsとstateの扱いについては概ね上記の特徴を念頭において使用しています。
より相応しい使い方やコードの組み方があるかと思いますが、僕自身がReact及びJavaScriptを勉強しながら作成しているので、その点ご理解頂けますと幸いです。

バリデーション付きフォームの作成

早速ですが、今回作成したバリデーション付きフォームがこちらです。

See the Pen Reactを使ったフォーム by くりはら (@kuriative) on CodePen.

各フォームの検証のため全てを必須項目に設定し、お名前・住所・メッセージは1文字以上、都道府県は”都道府県”以外、電話番号・メールアドレスは正しい形式で値が入力されたときに送信ボタンが有効化されます。
また、不正な値を入力した状態で入力フォームからフォーカスを外すとエラーを示すツールチップが表示されます。

今回はあくまで入力画面だけの作成です。
どうやらReactをさらに活用すると実際にメールを送信するところまで作成することが出来るようです。

フォーム部品の出力

まずは必要なinputやtextareaなどフォーム部品とそのレイアウトを設定します。

今回はtableを使用して作成します。

ハイライトしている8~13行目・15行目で別で用意したコンポーネントを呼び出しています。
FormInputRequiredやFormSendについているプロパティがpropsで受け渡しをしている値になります。

  • title … thタグに入る項目名
  • type … inputタグのtypeに入る値
  • name … inputタグのnameに入る値
  • ph … inputタグのplaceholderに入る値
  • requiredValue … 必須指定されたinputコンポーネントに関数の受け渡し(上記コード内では省略中に表記)
  • erch … バリデーション結果がエラーだった場合に動的にclassを付与する関数の受け渡し
  • value … 送信ボタンのvalueに入る値
  • disabled … 送信ボタンのdisabledに入る値

それぞれこのようになっています。

では次にinputなどの入力部品のコンポーネントです。

<FormInput /> … 通常のinput

今回は使用していませんが、必須入力の不要なinputタグを使いたい時には<FormInput />を使用することで出力することが出来ます。

<FormInputRequired /> … 必須入力のinput

この2つのinput用コンポーネントにある{this.props.◯◯}というプロパティで先ほど親になるコンポーネントで指定した値を受け取っています。
propTypesでは受け取るpropsの型を定義し、想定外の値の受け取りが内容に設定しています。
バリデーション機能部分になるrequiredValidatについては後述します。
propsを上手く使えば通常用と必須用とでコンポーネントを1つで出力分けが出来ると思いますが、今回は余力不足でこのような形に…。

<FormPref /> … 都道府県用select

getDefaultPropsで都道府県の値を全て入力し、それをpropsで値を渡すことでより柔軟に且つコードの肥大化を防いでいます。

この記述方法に関しては以下の記事を参考にさせていただきました。

参考記事:React.jsでFormを扱う

<FormMessage /> … メッセージ用textarea

今回はメッセージ項目以外でtextareaを使用する予定が無かったのでthに直接メッセージと入力してしまっています。

<FormSend /> … 送信ボタン用input

getDefaultPropsでdisabledとvalueの値を初期値として設定しています。

フォーム部品については以上です。
最後に必ず忘れずにコンポーネントをHTMLに出力しましょう。今回は#contentのついたformタグ内に出力しています。
本来であればformタグもReact内で扱うべきですが、formタグに設定するイベントなどを従来通り設定しやすいようにあえて外しています。

バリデーション機能の実装

フォームの出力が出来たら次はバリデーション機能を実装していきます。

14行目に指定しているonChangeとonBlurでフォームに入力があったときとフォーカスが外れたときにrequiredValidatを実行しています。
onChangeは入力中でも送信ボタンを有効に、onBlurは入力後にバリデーションがエラーだった場合に表示するツールチップのために設定しています。

requiredValidat内ではアクションのあったフォームからtypeとvalue値を引数にしコールバック関数として親コンポーネントに伝えています。

次に親コンポーネント内でのバリデーション処理です。

初めに2~8行目で送信ボタンのdisabled値とツールチップに出力するclass名を設定しています。

10~133行目は先ほどのコンポーネントから渡ってきた値を参照して愚直にswitch文でバリデーションチェックを行い各項目のフラグを立てています。
都道府県のチェック項目では”都道府県”は未入力時の初期値として扱うため、”都道府県”以外が選択されたかどうかをチェックしています。
電話番号・メールアドレスのチェック項目では予め変数に入れておいた正規表現を使ってチェックしています。
それらと同時にツールチップを起動させるためのclass名を再設定しています。

そして135~140行目で全ての必須項目のフラグが立っている場合にバリデーションチェック完了であればvalFlgにtrueを代入しフラグを立てています。

最後にvalFlgの値がtrueの時に送信ボタンのdisabledとvalue値を再設定しています。

以上で、バリデーション機能の実装は完了です!
Reactの全文がこちら

See the Pen Reactを使ったフォーム by くりはら (@kuriative) on CodePen.

フォームの最終調整

フォームが機能したので残すはツールチップの動きやCSSによるレイアウトです。
今回のテーマとして「Reactだけで作る」という縛りをつけていたのでツールチップについてもCSS3を使い動きを実装しています。
CSSについての解説は割愛させていただきます。詳細については上記実装画面のSCSSタブをご参照ください。

今後このようなReactを使用したVirtualDOMと呼ばれる手法での表現が一般化していくとすると、フロントエンドエンジニアとしては覚えることが増え作業自体も複雑になるように思います。
しかし慣れてしまえばメンテナンス性も良く、より手軽にこういった高機能を搭載したページを作成することが出来るようになります。

Reactは基本的にコンポーネントを扱う物としての役割だと思うので、この他にNode.jsやjQueryを併用することでさらに表現の幅は広がります。

React.js、やはりかなり奥が深いです…。


Previous: AngularJSを使ってお問合せフォームの作成! Next: サイトのビジュアル分析

© 2017 ALL CONNECT Inc. All Rights Reserved.