SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

基礎からはじめるReact入門

Reactによるフォーム/リストの基本

基礎からはじめるReact入門 第4回

Formコンポーネントを作る

 Formコンポーネントは掲示板アプリの入力部分です。名前の入力欄(input要素)、年齢の入力欄(select要素)、本文(textarea要素)の3個の入力欄と、送信ボタン(input要素)からなり、form要素で囲まれている、古典的なHTMLのフォームです(図4)。

図4 フォームの構成
図4 フォームの構成

 また、stateとpropsは次のような構造です。

Formコンポーネントのstate
名前 備考
name string -
age string Agesからひとつ選択
body string -

 Agesは次のように、年齢の選択肢を提供するオブジェクトです。

export const Ages = {
  TEEN: "teen",
  TWENTIES: "twenties",
  THIRTIES: "thirties",
  FOURTIES: "fourties",
  FIFTIES: "fifties",
}

 Listコンポーネントでも使用するため、exportしてあります。

Formコンポーネントのprops
名前
onSubmitNewPost ({ name, age, body }) => void

 onSubmitNewPostは、前述の通りAppコンポーネントに投稿データを送る関数オブジェクトです。

form要素の扱い

 Reactでform要素を扱う際には、次の方針が採用されることが多いです。

  • stateが持つ状態を入力欄に反映する。
  • 各入力欄への入力内容をstateへ随時保存する。
  • 送信ボタンが押された時点でのstateを送信対象として取りまとめて、propsの関数に渡す。

 form要素が本来持っている送信などの機能は使わずに、JavaScript側でイベントをハンドリングする形になります。

 それでは、コンポーネントの実装を見ていきましょう。

単一行テキストへの入力を扱う

 まずは、入力値をstateに反映する方法について、名前の入力欄を例に挙げて解説します。JSXとしてはtype属性をtextにしたinput要素を使って、次のような形で実装します。

<div>
  <label>
    名前:
    <input
      type="text"
      value={this.state.name}
      onChange={(event) => this.handleChangeName(event)} />
  </label>
</div>

 今回の実装方針では、フォームに表示されるべき正しい値をstateが持っています。そのため、stateの内容に沿ってinput要素が表示されるよう、value属性にstateの内容を渡しています。

 そして、入力があった場合には、onChangeに登録されたコールバックが呼ばれます。event.target.valueにDOMから渡された入力値が入っているので、そのままstateに登録すればOKです。

handleChangeName(event) {
  this.setState({
    name: event.target.value
  });
}

セレクトボックスの選択を扱う

 select要素を扱う場合も、input要素の場合とほとんど変わりません。JSXは次のように実装します。

<div>
  <label>
    年齢:
    <select
      value={this.state.age}
      onChange={(event) => this.handleChangeAge(event)}>
      <option value={Ages.TEEN}>10代</option>
      <option value={Ages.TWENTIES}>20代</option>
      <option value={Ages.THIRTIES}>30代</option>
      <option value={Ages.FOURTIES}>40代</option>
      <option value={Ages.FIFTIES}>50代</option>
    </select>
  </label>
</div>

 また、コールバックは次のように実装します。event.target.valueに、option要素のvalue属性に指定してあった値が渡される点に注目してください。

handleChangeAge(event) {
  this.setState({
    // option要素のvalueが渡される
    age: event.target.value
  });
}

複数行テキストへの入力を扱う

 textarea要素を扱う場合は、input要素の場合とまったく同じ扱いをします。JSXは次のように実装します。

<div>
  <label>
    本文:
    <textarea
      value={this.state.body}
      onChange={(event) => this.handleChangeBody(event)} />
  </label>
</div>

 また、コールバックは次のように実装します。

handleChangeBody(event) {
  this.setState({
    body: event.target.value
  });
}

 3種類の入力欄について説明してきました。通常のフォームの扱いとあまり変わりませんね。これで、入力された値を常にstateに保持しておけるようになりました。

送信ボタンのイベントハンドリングを行う

 stateに値が入ったら、あとは送信ボタンを押すだけです。次のように、送信のinput要素は通常のHTMLと変わりありません。

<input type="submit" value="送信" />

 一方で、form要素の扱いは少し特殊です。送信先のURLなどはここには登録せず、次のようにonSubmitを使ってイベントを拾います。

<form onSubmit={(event) => this.handleSubmit(event)}>

 コールバックの実装は次のように行いました。

handleSubmit(event) {
  // submitのデフォルト動作では
  // 画面が再描画されてしまうので阻止する
  event.preventDefault(); // (1)

  const { name, age, body } = this.state;
  // 投稿する
  this.props.onSubmitNewPost({ // (2)
    name,
    age,
    body,
  });
  // フォームの内容をリセットする
  this.setState({
    ...this.createInitialForm()
  });
}

 onSubmitのイベントハンドリングで最も重要なのは、(1)のpreventDefault呼び出しです。これを実行しなかった場合、form要素のデフォルトの動作により、ページがリロードされてしまいます。シングルページアプリケーションとしては致命的な挙動になるので、忘れずに呼び出しましょう。

 十分にバリデーションを行ったら、最後に送信用の関数を呼び出します(2)。これで、Appコンポーネントに送信内容が渡されました。

次のページ
Listコンポーネントを作る

この記事は参考になりましたか?

基礎からはじめるReact入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 中川 幸哉(ナカガワ ユキヤ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10593 2017/12/28 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー