序章

redux-form は、Reduxを利用したフォームを管理するための優れた方法です。 これは、 react-redux を使用してReactのHTMLフォームがすべての状態を保存するためにReduxを使用することを確認するHigher-Order-Component(HOC)です。

redux-formには、アプリケーションの構築に役立つ次のコンポーネントがあります。

  • formReducer():これは、アプリケーションからの変更に基づいてReduxストアを更新する方法を指示する関数です。 これらの変更は、Reduxアクションによって記述されます。 formReducer でRedux状態にマウントする必要があります form.

  • reduxForm()reduxForm() 関数は高階コンポーネントであり、構成オブジェクトを受け取り、常に新しい関数を返します。 これは、フォームコンポーネントをラップし、ユーザーインタラクションをReduxディスパッチアクションにバインドするために使用されます。

  • The <Field/> コンポーネント:ラップされたフォームコンポーネント内に存在するコンポーネント。 これは、フォーム内の入力要素をに接続する方法として機能します。 redux-form logic. 言い換えれば、それはユーザーが入力したものから入力を取得する方法です。

あなたはについてもっと読むことができます redux-form ドキュメントのAPI。

このチュートリアルでは、 redux-form を使用して、検証付きのフォームを作成し、Reduxストアに接続します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

ステップ1-プロジェクトの作成

create-react-appパッケージを使用してReactアプリを構築します。 create-react-app ビルド構成なしでReactアプリを作成できます。 使用できます create-react-app 次のターミナルコマンドを実行します。 それは自動的にあなたのためのReactアプリをというタイトルのフォルダに作成します contact-redux.

  1. npx create-react-app contact-redux

注意することが重要です npx のバージョンでのみ動作します npm 5.2以上です。 それより前のバージョンをお持ちで、それでも使用したい場合 create-react-app お使いのコンピュータで。 以下のターミナルコマンドを実行してインストールします create-react-app Reactアプリを起動します。

  1. npm install -g create-react-app
  2. create-react-app contact-redux

ディレクトリに移動し、開発サーバーを起動して、すべてが機能することを確認します。 次のコマンドを実行して、新しく作成されたReactアプリを開発モードで起動します。

  1. npm start

ブラウザに次のように表示されます。

これで、Reactアプリが稼働しています。

次のコマンドを実行して、フォームに必要な依存関係を追加します。

  1. npm install --save redux react-redux redux-form
  • redux -状態コンテナであり、redux-formが機能するための前提条件です。
  • react-redux -React ReduxはReduxの公式Reactバインディングであり、redux-formが機能するための前提条件でもあります
  • redux-form-このチュートリアルで使用されているパッケージ。

インストールが完了すると、お問い合わせフォームで作業できます。

ステップ2–フォームの作成

BulmaCDNリンクをに追加します index.html いくつかのデフォルトのスタイルを追加するためにファイル。 を開きます public/index.html ファイルを作成し、次のコード行を head 鬼ごっこ:

public / index.html
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css">

にいくつかの編集を行います src/App.js 今すぐファイルします。 開く src/App.js ファイルを作成し、ファイルの先頭に以下のコード行を追加します。

src / App.js
import { reduxForm, Field } from 'redux-form';

次に、 render() 関数を作成し、次のコードで変更します。

src / App.js
render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React x redux-form</h1>
        </header>
        <div className="container">
          <p className="App-intro">
            Contact Form
          </p>
          <SignInForm />
        </div>
      </div>
    );
  }

紹介文が変更され、最も重要なのは、 <SignInForm /> 以下で作成するコンポーネント。 必要なフォームを返すシンプルなコンポーネントになり、に接続されます redux-form 成分。 同じように src/App.js ファイルの場合、宣言の直前にこのコードを入力します class App extends Component.

src / App.js
let SignInForm = props => {
  return <form className="form">
    <div className="field">
      <div className="control">
        <label className="label">First Name</label>
        <Field className="input" name="firstName" component="input" type="text" placeholder="First Name"/>
      </div>
    </div>

    <div className="field">
      <div className="control">
        <label className="label">Last Name</label>
        <Field className="input" name="lastName" component="input" type="text" placeholder="Last Name"/>
      </div>
    </div>

    <div className="field">
      <div className="control">
        <label className="label">Email</label>
        <Field className="input" name="email" component="input" type="email" placeholder="Email Address"/>
      </div>
    </div>

    <div className="field">
      <div className="control">
        <label className="label">Proficiency</label>
        <div className="select">
          <Field className="input" name="proficiency" component="select">
            <option />
            <option value="beginner">Beginner Dev</option>
            <option value="intermediate">Intermediate Dev</option>
            <option value="expert">Expert Dev</option>
          </Field>
        </div>
      </div>
    </div>

    <div className="field">
      <div className="control">
        <label className="label">Age</label>
        <Field className="input" name="age" component="input" type="number" placeholder="Age"/>
      </div>
    </div>

    <div className="field">
      <div className="control">
        <label className="checkbox">
          <Field name="saveDetails" id="saveDetails" component="input" type="checkbox"/>
          Save Details
        </label>
      </div>
    </div>

    <div className="field">
      <div className="control">
        <label className="label">Message</label>
        <Field className="textarea" name="message" component="textarea" />
      </div>
    </div>

    <div className="field">
      <div className="control">
        <button className="button is-link">Submit</button>
      </div>
    </div>

  </form>;
};

このコードでは、名、姓、年齢などの情報をユーザーに尋ねる最小限の連絡フォームを設定します。 この形式の興味深いビットは Field 成分。

The Field コンポーネントはから来ます redux-form パッケージとそれは私たちが書く方法です input 分野。 The type propは、入力のタイプを示します。つまり、 radio 入力、 checkbox 入力、 text 入力または email 入力。 The component propは、入力フィールドのタイプを決定します。 input, textarea また select タグと name propは、以下で作成するreduxストアのフィールドの状態を識別するために使用されるものです。

したがって、redux-formに接続されたフォームを使用するには、ある種のReduxストアをすでに作成しておく必要があります。これを次に行います。

ステップ3–Reduxストアを設定する

フォームコンポーネントを接続できるReduxストアが必要です(SignInForm)作成しました。 インポートすることから始めましょう redux パッケージ。 を開きます src/index.js ファイルを作成し、基本的にインポートしている次のコード行を追加します redux Reactアプリに。

src / index.js
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { reducer as formReducer } from 'redux-form';

コードの最初の行はインポートします createStorecombineReducers. createStore は、アプリの完全な状態ツリーを保持するReduxストアを作成するのに役立ち、 combineReducers は、すべてのレデューサー関数を1つのヘルパー関数に管理してから渡すことができます。 createStore. これらの関数の詳細については、ReduxAPIリファレンスページをご覧ください。

コードの2行目はインポートします Provider から react-redux. Provider ストアの状態をアプリ内のすべてのコンテナーコンポーネントに渡すのに役立ちます。これがどのように機能するかについては後で説明します。

コードの3行目はインポートします reducer なので formReducer これを使用して、フォームをReduxストアに接続します。

次に、実際のReduxストアを作成し、を使用してすべてのコンテナコンポーネントに適用できることを確認します。 Provider 成分。 編集します src/index.js 次のコードブロックを持つファイル。

src / index.js
import React from 'react';
import ReactDOM from 'react-dom';

import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { reducer as formReducer } from 'redux-form';

import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

const rootReducer = combineReducers({
  form: formReducer,
});

const store = createStore(rootReducer);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

registerServiceWorker();

上記のコードブロックでは、 combineReducers 接続する機能 formReducer フォームからReduxストアまで。 これは基本的に、アクション(この場合はフォームの変更)に応じて状態を更新するために使用されます。 次のコード行は、を使用してストアを作成するために使用されます createStore Reduxから。

この新しく作成されたストアは、アプリのすべての部分で利用できるようになります。 Provider 包まれている App コンポーネントとそれはまたである店の小道具を受け入れます store それは上で作成されました。

フォームに戻り、最後にストアに接続しましょう。

##ステップ4–フォームをredux-formに接続する

フォームコンポーネントがありますが、に接続されていません redux-form まだ。 それを修正しましょう。 このコードブロックを、 class App extends Component SignInFormプレゼンテーションコンポーネントの宣言の直後。

src / index.js
SignInForm = reduxForm({
  form: 'signIn',
})(SignInForm);

上記のコードブロックでは、 SignInForm を使用してredux接続形式になります reduxForm 高階コンポーネント。 これは、フォームがストアに接続されたことを意味します。 注意すべきことの1つは、構成キーです form、識別子として使用され、フォームコンポーネントに一意の名前を提供するために使用されます。 それらが複数の形式である場合、それらの異なる状態をより適切に管理するために、別々の名前を使用する必要があります。

次に行う必要があるのは、[送信]ボタンをクリックしたときに何が起こるかを構成することです。 理想的なアプリでは、リモートAPIまたは一部のデータベースにデータを送信する必要がありますが、デモンストレーションの目的で、フォームデータをブラウザーコンソールに記録します。 そのためには、小道具からフォームデータを取得し、それらをどこかに保存する必要があります。

内部 SignInForm コンポーネントのすぐ上にコード行を追加します return 声明。

[label src/index.js]  
  const { handleSubmit } = props;
  return <form **onSubmit={handleSubmit}** className="form">

The props の中に SignInForm フォームはに分解されます handleSubmit. The handleSubmit 関数は、フォームでハンドラーとして使用されます。 onSubmit 送信ボタンがクリックされたときのイベント。

最後に、 App のコンポーネント src/App.js ファイルの場合、フォームデータをブラウザコンソールに記録する関数を作成します。 以下のコードブロックをファイルの直前のファイルに追加します render() 関数。

src / App.js
  handleSignIn = values => {
		console.log(values);
	};

次に、 handleSignIn のイベントハンドラとして機能します SignInForm 成分。 redux-form フォームから取得したデータを自動的に確認します。これは基本的に SignInForm コンポーネントは、おかげでコンソールに記録する必要があります handleSubmit 上記の機能。

src / App.js
    <SignInForm onSubmit={this.handleSignIn} />

これで、を実行してアプリを起動できます npm start ターミナルコマンド。 フォームに記入し、[送信]をクリックすると、コンソールに記録された値が表示されます。

ステップ5–検証を追加する

フォームの作成と redux-form いくつかの検証機能が付属しており、これを実装します。 の中に src/App.js ファイルに、以下のコードブロックを入力します。

src / App.js
const validate = val => {
  const errors = {};
  if (!val.firstName) {
    console.log('First Name is required');
    errors.firstName = 'Required';
  }
  if (!val.lastName) {
    console.log('Last Name is required');
    errors.lastName = 'Required';
  }
  if (!val.email) {
    console.log('email is required');
    errors.email = 'Required';
  } else if (!/^.+@.+$/i.test(val.email)) {
    console.log('email is invalid');
    errors.email = 'Invalid email address';
  }
  if (!val.age) {
    errors.age = 'Required'
  } else if (isNaN(Number(val.age))) {
    errors.age = 'Must be a number'
  } else if (Number(val.age) < 18) {
    errors.age = 'Sorry, you must be at least 18 years old'
  }
  return errors;
};

The validate 関数は、フォームの検証エラーをチェックするために使用されます。 The val パラメータは、さまざまなフィールドの検証をチェックするために使用されます。 まず、 errors オブジェクトが空です。空のオブジェクトは明らかにエラーがないことを意味します。 次に、条件付きロジックを使用して、フィールドが空であるかどうかを確認します。空である場合は、対応するエラーをスローします。 上記のコードブロックでは、次の検証のみを行っています firstName, lastName, email、 と age. の中に email 検証条件付きで、それが空であるかどうかをチェックし、それが有効な電子メールであるかどうかもチェックします。 regex とで age 検証条件付きで、それが空であるかどうか、数値であるかどうか、およびユーザーが18未満であるかどうかを確認します。

次に、検証関数をに登録します redux-form 検証テストの実行に使用を開始できるようにします。 追加します validate 機能する redux-form 高階コンポーネント:

src / index.js

SignInForm = reduxForm({
  form: 'signIn',
  validate,
})(SignInForm);

これで、検証関数の準備が整い、に登録されました。 redux-form HOC、エラーが発生するたびにエラーを表示する再利用可能なコンポーネントを構築し、フォームで新しく作成されたコンポーネントを使用します。

src / index.js


const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
  <div>
    <div className="control">
      <label className="field">{label}</label>
      <input className="input" {...input} placeholder={label} type={type}/>
      {touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))}
    </div>
  </div>
)

The renderField コンポーネントは、の小道具を取り入れます input オブジェクト、 labeltype 入力と meta これは redux-form 財産。 この線 {touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))} フォームフィールドがクリック/フォーカスされたときにエラーがあるかどうかを示すエラーメッセージが表示されることを意味します。 また、エラーが発生した場合、フォームは送信されません。

ここで、フォームをチェックして無効な入力を入力しようとしたり、検証テストのあるフィールドをスキップしたりすると、フォームの下にエラーメッセージが表示されます。

結論

このチュートリアルでは、でフォームを作成しました redux-form そしてそれをReduxストアに接続しました。 外部スキーマ検証ツールを必要とせずに、フォームに同期検証を追加しました。

あなたはについてもっと読むことができます redux-form 公式サイトで、の例を調べてさらに詳しく調べることができます。

このチュートリアルの完成したコードは、GitHubにあります。