ReactとFormikを備えたティアフリーフォーム
少なくとも1つのフォームを含まないWebアプリを作成することはめったにありません。 多くの場合、アプリ全体は単なる一連のフォームです。 これらの各フォームには、状態管理、イベントハンドラー、および多くの場合、ある種のクライアント側のデータ検証が必要です。 Formik は、これらすべてを小さなパッケージで、そして彼らが主張するように「涙なしで」行うことを目指しています。
入門
formik
の使用を開始するには、npm
またはyarn
を介してプロジェクトに追加する必要があります。
$ npm install --save formik # or $ yarn add formik
依存関係を追加したら、それを使用するプロジェクトに必ずインポートしてください。 この記事では、Formik
とForm
ヘルパーコンポーネントの両方を使用します。
import { Formik, Form } from "formik";
Form
コンポーネントは、標準のform
要素のラッパーであり、Formik
コンポーネントに接続されたonSubmit
ハンドラーを自動的に接続し、さらに時間を節約します。
Formikコンポーネント
Formikの本当の魔法は、Formik
コンポーネントで発生します。 このコンポーネントは、フォームをまとめるために使用され、レンダリングプロップを介して状態値とハンドラーを公開します。
このコンポーネントは、プロパティを取得してデフォルト値を設定し、送信された値を検証し、送信を処理できます。
Formik
コンポーネントが、後で作成する基本的なログインフォームを検索する方法は次のとおりです。
<Formik // Sets up our default values initialValues={{ email: "", password: "" }} // Validates our data validate={values => { const errors = {}; if (!values.email) errors.email = "Required"; if ( !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) ) { errors.email = "You must supply a valid email address"; } if (values.password.length < 8) { errors.password = "Passwords must be at least 8 characters"; } if (values.email === values.password) { errors.password = "Your password shouldn't be the same as your email"; } return errors; }} // Handles our submission onSubmit={(values, { setSubmitting }) => { // This is where you could wire up axios or superagent console.log("Submitted Values:", values); // Simulates the delay of a real request setTimeout(() => setSubmitting(false), 3 * 1000); }} > {props => ( <div>This is where your Form and form elements will go!</div> )} </Formik>
yupやjoiなどのオブジェクトスキーマバリデーターに精通している場合は、validate
プロパティをスキップしてvalidationSchema
を渡すことができます。代わりは。
フォームコンポーネント
前述のように、Form
コンポーネントは、onSubmit
ハンドラーなどを自動的に接続するform
要素のドロップイン置換です。
通常どおりにフォームの入力をラップするために使用します。
<Formik> {props => ( <Form> <label>My Input</label> <input type="text" /> </Form> )} </Formik>
入力の状態
すぐに使用できるFormikのrenderプロパティは、イベントハンドラーを公開して、フォーム入力への変更(「タッチ」されているかどうか、値、エラーなど)を管理します。
フォーム全体については、フォームが検証中か送信中か、およびフォームを簡単にリセットできるイベントハンドラーを確認できます。
props.values
およびprops.errors
は、フォームフィールドに対応するプロパティを持つオブジェクトです。
props.handleChange
およびprops.handleBlur
をonChange
およびonBlur
プロパティに渡して、変更と入力が「タッチ」されたかどうかを追跡できます。
この「タッチされた」値は、ページの読み込み時ではなく、ユーザーが要素を操作した後にのみエラーを表示する場合に役立ちます(これはIMHOが推奨されます)。
props.dirty
は、ユーザーがフォームを変更するとtrueに設定されます。
状態値props.isValidating
およびprops.isSubmitting
は、ユーザーがプロセスのどの段階にあるかを示します。 ローダーを表示したり、フォームや個々のボタンを無効にしたりするのに最適です。
すべてをまとめる
正式にFormikedされた後の、電子メールとパスワードを使用した単純なログインフォームは次のようになります。
<Formik // Sets up our default values initialValues={{ email: "", password: "" }} // Validates our data validate={values => { const errors = {}; if (!values.email) errors.email = "Required"; if ( !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) ) { errors.email = "You must supply a valid email address"; } if (values.password.length < 8) { errors.password = "Passwords must be at least 8 characters"; } if (values.email === values.password) { errors.password = "Your password shouldn't be the same as your email"; } return errors; }} // Handles our submission onSubmit={(values, { setSubmitting }) => { // This is where you could wire up axios or superagent console.log("Submitted Values:", values); // Simulates the delay of a real request setTimeout(() => setSubmitting(false), 3 * 1000); }} > {props => ( <Form> <label htmlFor="email">Email</label> <div> <input name="email" type="email" placeholder="Enter your account email" value={props.values.email} onChange={props.handleChange} onBlur={props.handleBlur} style={{ borderColor: props.errors.email && props.touched.email && "red" }} /> {props.errors.email && props.touched.email && ( <div style={{ color: "red" }}>{props.errors.email}</div> )} </div> <label htmlFor="password">Password</label> <div> <input name="password" type="password" placeholder="Enter your account password" value={props.values.password} onChange={props.handleChange} onBlur={props.handleBlur} style={{ borderColor: props.errors.password && props.touched.password && "red" }} /> {props.errors.password && props.touched.password && ( <div style={{ color: "red" }}>{props.errors.password}</div> )} </div> <input type="submit" value="Submit" disabled={props.isSubmitting} /> <input type="reset" value="Reset" onClick={props.handleReset} disabled={!props.dirty || props.isSubmitting} /> </Form> )} </Formik>
結論
Formikは、フォームを作成するための使い慣れたレンダリングプロップベースのアプローチを提供します。
通常作成する冗長なボイラープレートとステートメント管理ロジックのほとんどは、フォームでかなり複雑な状態管理を実行するのに十分な電力を内部で提供しながら、適切に処理されます。
この記事のコードを試してみたい場合は、CodeSandboxで確認できます。
乾杯!