LoginSignup
26
25

More than 5 years have passed since last update.

react.js/material-uiでコンポーネントでhtml5のinputタグを使ってバリデーション

Last updated at Posted at 2015-08-21

react.jsとmaterial-uiを使うと、入力フィールドとそのバリデーションは次のようなコードになります。今回はメールアドレスを入力するケースです。

※ ES6の記法で書いています。


handleValidation(e) {
  let email = this.refs.email;
  let value = email.getValue();
  if (!value) {
    email.setErrorText('メールアドレスを入力してください');
    return;
  }
  let re = /^.+@.+$/i;
  if (!re.test(email)) {
    email.setErrorText('入力された値はメールアドレスではありません');
    return;
  }
}

render() {
  return <TextField ref='email' floatingLabelText='email'
           onChange={this.handleValidation.bind(this)} />;
}

のように記述します。html5のタグが使えるのに、メリットを全然活かせていません。TextFieldにセットしたプロパティはすべて、inputタグにセットされるので、type='email'をセットします。ここでは一緒に、required=trueをセットして、入力を必須にセットしています。

render() {
  return <TextField ref='email' floatingLabelText='email'
           type='email' required={true}
           onChange={this.handleValidation.bind(this)} />;
}

これで、inputタグのtypeはemailになりました。しかし、html5のinputタグのバリデーションはフォームをサブミットするときに実行されて表示されます。さらにonChangeで自前でemailのバリデーションを行うのもの二度手間です。もっとスッキリとしたいです。

inputタグは値が入力されると、即座にバリデーションされてvalidationMessageにバリデーションメッセージがセットされます。これを使えば、バリデーションのロジックを自分のコードから減らせて、表示方法もコントロールできます。

material-uiに限った話で言えば、input要素はdiv要素の中にラップされているので、reactのコンポーネントからDOM要素を抜き出す、と言う余分な処理が入りますが、やり方自体はreact.jsに限らず汎用的に使えるはずです。

それでは、バリデーションメッセージを処理するようにhandleValidationを書き換えます。

handleValidation() {
  let email = this.resf.email;
  let elem = React.findDOMNode(email).getElementsByTagName('input')[0];
  if (!elem.validity.valid) {
    email.setErrorText(elem.vaidationMessage);
  } else {
    email.setErrorText('');
  }
}

これで、入力値のバリデーションがhtml5の機能で隠蔽されました。また、ブラウザの機能でかっこわるいバリデーションエラーを見せるのではなく、Material UIの統一的なエラーメッセージの表示方法でエラーを見せられるようになります。

26
25
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
26
25