ReactとFormikでログインフォームを検証する方法
序章
Webアプリケーションのフォーム要素が有効なデータを返していることを確認するには、コードに自動検証を組み込むと便利です。 これはReactにも当てはまります。早い段階でフォーム検証を作成することで、将来的にエラーが発生するのを防ぐことができる場合が多いからです。
Reactでは、フォームの操作と検証は少し冗長になる可能性があります。 コードを管理しやすくするために、Formikなどのパッケージを使用してフォームを作成できます。
このチュートリアルでは、Reactプロジェクトを作成し、Formikパッケージを追加し、onSubmitコールバックとエラーメッセージ用のvalidate関数を使用してFormikコンポーネントをカスタマイズし、それらのエラーメッセージをに表示します。ユーザー。
このチュートリアルを終了すると、CodeSandboxでこのライブサンプルのようなプロジェクトが作成されます。
前提条件
- Node.jsはローカルにインストールされます。これは、Node.jsのインストール方法とローカル開発環境の作成方法に従って実行できます。
- Reactアプリの作成。これは、Reactプロジェクトの設定方法に従って実行できます。
ステップ1—プロジェクトの設定
CreateReactAppを使用してプロジェクトを作成します。 チュートリアルの目的で、プロジェクトにvalidate-react-login-formという名前を付けることができます。
npx create-react-app validate-react-login-form
これで、プロジェクトディレクトリに移動し、ノードサーバーを起動して、Webブラウザで表示できます。
cd validate-react-login-form npm start
yarnがインストールされている場合、メッセージでnpm startの代わりにyarn startを使用するように指示される場合があります。 npm命令が必要な場合は、プロジェクトの作成時に-use-npmフラグを使用できます。 このチュートリアルでは、yarnまたはnpmのいずれかを使用できます。
このプロジェクトディレクトリをお気に入りのエディタで開いて、ファイルを作成および変更することもできます。
Create React Appにはいくつかのファイルが含まれますが、このチュートリアルでは、index.js、index.css、ValidatedLoginForm.jsの3つのファイルのみを直接作成または変更します。
ステップ2—依存関係のインストール
最初のプロジェクトが作成されたので、 Formik 、 email-validator 、およびYupの3つのパッケージをインストールします。
Formik により、検証、エラーメッセージ、およびフォーム送信の処理がより管理しやすくなります。
ターミナルにFormikをインストールします。
npm install formik
email-validator は、電子メールの検証に使用される小さなパッケージです。
端末の場合は、email-validatorをインストールします。
npm install email-validator
Yup は、Formikと組み合わせて一般的に使用されるスキーマバリデーターです。
ターミナルにYupをインストールします。
npm install yup
必要なパッケージをインストールしたので、検証済みのフォームコンポーネントを作成する準備が整いました。
ステップ3—検証済みフォームコンポーネントを作成する
依存関係をインストールしたので、ValidatedFormComponentの作成を開始できます。 今のところ、基本を作成し、アプリのルートファイルにインポートして表示します。
これを行うには、次のようにします。
- 新しい機能コンポーネントを作成する
- ダミー表示コンテンツを追加
index.jsにインポートします
srcディレクトリにValidatedLoginForm.jsという名前の新しいファイルを作成します。 そのファイル内に、機能コンポーネントの基本コードを追加します。
src / ValidatedLoginForm.js
import React from "react";
const ValidatedLoginForm = () => (
<div>
<h1>Validated Form Component</h1>
</div>
);
export default ValidatedLoginForm;
次に、それをindex.jsファイルに含めます。
src / index.js
import ValidatedLoginForm from "./ValidatedLoginForm";
次に、コンポーネントを参照します。
src / index.js
<ValidatedLoginForm />
これらすべてを組み合わせると、index.jsは次のようになります。
src / index.js
import React from "react";
import ReactDOM from "react-dom";
import ValidatedLoginForm from "./ValidatedLoginForm";
function App() {
return (
<div className="App">
<h1>Validated Login Form</h1>
<ValidatedLoginForm />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
フォームコンポーネントが表示されます。
それでは、Formikを実装するためにValidatedLoginForm.jsに戻りましょう。
まず、Formik、email-validator、Yupを新しいコンポーネントにインポートします。
src / ValidatedLoginForm.js
import { Formik } from "formik";
import * as EmailValidator from "email-validator"; // used when validating with a self-implemented approach
import * as Yup from "yup"; // used when validating with a pre-built solution
それでは、初期値を使用してFormikタグを記述してみましょう。 初期値は、最初に状態を設定するものと考えてください。
onSubmitコールバックも必要です。 このコールバックは、分解できる2つのパラメーター、値とオブジェクトを受け取ります。 値は、フォームからの入力値を表します。 ここにダミーコードを追加して非同期ログイン呼び出しをシミュレートし、値をログアウトします。
コールバックで、2番目のパラメーターから分解されたsetSubmitting関数を呼び出します。 これにより、非同期ログイン呼び出しが行われているときに送信ボタンを有効または無効にできます。
src / ValidatedLoginForm.js
<Formik
initialValues={{ email: "", password: "" }}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
console.log("Logging in", values);
setSubmitting(false);
}, 500);
}}
>
<h1>Validated Login Form</h1>
</Formik>
小道具をレンダリングする
Formikコンポーネントは、レンダリングプロップを使用して、作成するフォームに特定の変数と関数を提供します。
つまり、レンダリングプロップは、コンポーネントの子要素にプロパティを渡すために使用されます。 この場合、Formikは子であるフォームコードにプロパティを渡します。 いくつかの特定の変数と関数への参照を取得するために破壊を使用していることに注意してください。
src / ValidatedLoginForm.js
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
return (
<div>
<h1>Validated Login Form</h1>
</div>
);
}}
この時点で、ValidatedLoginForm.jsは次のようになります。
import React from "react";
import { Formik } from "formik";
import * as EmailValidator from "email-validator";
import * as Yup from "yup";
const ValidatedLoginForm = () => (
<Formik
initialValues={{ email: "", password: "" }}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
console.log("Logging in", values);
setSubmitting(false);
}, 500);
}}
>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
return (
<div>
<h1>Validated Login Form</h1>
</div>
);
}}
</Formik>
);
export default ValidatedLoginForm;
ステップ4—フォームを表示する
これで、フォームを表示するためのコードの記述を開始できます。 フォームには、2つの入力(電子メールとパスワード)、それぞれのラベル、および送信ボタンがあります。
src / ValidatedLoginForm.js
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit
} = props;
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
/>
<label htmlFor="password">Password</label>
<input
id="password"
name="password"
type="password"
placeholder="Enter your password"
/>
<button type="submit">
Login
</button>
</form>
);
}}
onSubmitが小道具からhandleSubmitを呼び出していることに注意してください。
以前、ユーザーがすでにログインしようとしているときに送信ボタンを無効にできると述べました。 以前の小道具から分解したisSubmittingプロパティを使用して、この変更を追加できます。
src / ValidatedLoginForm.js
<button type="submit" disabled={isSubmitting}>
Login
</button>
styles.cssファイルには次のCSSを使用できます。
src / styles.css
.App {
font-family: sans-serif;
}
h1 {
text-align: center;
}
form {
max-width: 500px;
width: 100%;
margin: 0 auto;
}
label,
input {
display: block;
width: 100%;
}
label {
margin-bottom: 5px;
height: 22px;
}
input {
margin-bottom: 20px;
padding: 10px;
border-radius: 3px;
border: 1px solid #777;
}
input.error {
border-color: red;
}
.input-feedback {
color: rgb(235, 54, 54);
margin-top: -15px;
font-size: 14px;
margin-bottom: 20px;
}
button {
padding: 10px 15px;
background-color: rgb(70, 153, 179);
color: white;
border: 1px solid rgb(70, 153, 179);
transition: ease-in-out background-color 250ms, ease-in-out color 250ms;
}
button:hover {
cursor: pointer;
background-color: white;
color: rgb(70, 153, 179);
}
また、styles.cssをindex.jsにインポートします。
src / index.js
import "./styles.css";
ステップ5—検証メッセージロジックの追加
次に、入力を検証しましょう。 最初のステップは、入力にどのような制約を課すかを決定することです。 メールから始めましょう。 メール入力は次のようにする必要があります。
- 必要とされます。
- 本物のメールのように見えます。
パスワードの入力は次のとおりです。
- 必要とされます。
- 少なくとも8文字の長さである必要があります。
- 少なくとも1つの番号が含まれています。
これらのメッセージを作成する2つの方法について説明します。1つは手動で、もう1つはYupを使用します。
独自のパスワード検証ソリューションを作成する
最初のオプションは、検証関数を自分で作成することです。 この関数の目的は、フォームの値を反復処理し、適切と思われる方法でこれらの値を検証し、valueとmessage。
Formikタグ内に、次のコードを追加することから始めます。 これにより、電子メールに常にInvalid emailエラーが追加されます。
src / ValidatedLoginForm.js
validate={values => {
let errors = {};
errors.email = "Invalid email";
return errors;
}}
これで、ユーザーが電子メールに何かを入力したことを確認できます。
src / ValidatedLoginForm.js
validate={values => {
let errors = {};
if (!values.email) {
errors.email = "Required";
}
return errors;
}}
次に、email-validatorパッケージを使用して、その電子メールが有効な電子メールであることを確認できます。 これは、電子メールの同等のチェックとほぼ同じように見えます。
src / ValidatedLoginForm.js
validate={values => {
let errors = {};
if (!values.email) {
errors.email = "Required";
} else if (!EmailValidator.validate(values.email)) {
errors.email = "Invalid email address.";
}
return errors;
}}
これでメールが処理されるので、パスワードフォームで作業します。 まず、ユーザーが何かを入力したことを確認します。
src / ValidatedLoginForm.js
validate={values => {
let errors = {};
if (!values.password) {
errors.password = "Required";
}
return errors;
}}
ここで、長さが少なくとも8文字であることを確認する必要があります。
src / ValidatedLoginForm.js
validate={values => {
const passwordRegex = /(?=.*[0-9])/;
if (!values.password) {
errors.password = "Required";
} else if (values.password.length < 8) {
errors.password = "Password must be 8 characters long.";
}
return errors;
}}
最後に、パスワードに少なくとも1つの数字が含まれていることを確認します。 このために、正規表現を使用できます。
src / ValidatedLoginForm.js
validate={values => {
let errors = {};
const passwordRegex = /(?=.*[0-9])/;
if (!values.password) {
errors.password = "Required";
} else if (values.password.length < 8) {
errors.password = "Password must be 8 characters long.";
} else if (!passwordRegex.test(values.password)) {
errors.password = "Invalid password. Must contain one number.";
}
return errors;
}}
完成したファイルは次のようになります。
src / ValidatedLoginForm.js
validate={values => {
let errors = {};
if (!values.email) {
errors.email = "Required";
} else if (!EmailValidator.validate(values.email)) {
errors.email = "Invalid email address.";
}
const passwordRegex = /(?=.*[0-9])/;
if (!values.password) {
errors.password = "Required";
} else if (values.password.length < 8) {
errors.password = "Password must be 8 characters long.";
} else if (!passwordRegex.test(values.password)) {
errors.password = "Invalid password. Must contain one number.";
}
return errors;
}}
サードパーティのパスワード検証ソリューションの利用
検証ロジックを自分で処理するのは少し複雑になることに気づいたかもしれません。 すべてのチェックを手動で行う必要があります。 うん、この作業の一部を節約できます。 Yupを使用すると、Validateプロパティは表示されなくなりますが、代わりにvalidationSchemaを使用してください。
メールから始めましょう。 Yupを使用した同等の検証は次のとおりです。
src / ValidatedLoginForm.js
validationSchema={Yup.object().shape({
email: Yup.string()
.email()
.required("Required")
})}
さて、パスワードについては:
src / ValidatedLoginForm.js
validationSchema={Yup.object().shape({
email: Yup.string()
.email()
.required("Required"),
password: Yup.string()
.required("No password provided.")
.min(8, "Password is too short - should be 8 chars minimum.")
.matches(/(?=.*[0-9])/, "Password must contain a number.")
})}
これで、フォームを検証するための2つの異なる方法について説明しました。 次に、エラーメッセージを表示するようにコードを更新します。
ステップ6—検証およびエラーメッセージの表示
エラーメッセージを作成するためのロジックができたので、それらを表示する必要があります。 これを行うには、フォームの入力を更新する必要があります。
電子メールとパスワードの両方の入力について、いくつかのプロパティを更新する必要があります。
valueonChangeonBlurclassName
電子メールフィールドへのレンダリングプロップの適用
value、onChange、およびonBlurを更新することから始めましょう。 これらはそれぞれ、レンダープロップのプロパティを使用します。
src / ValidatedLoginForm.js
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
/>
次に、エラーが発生した場合に備えて、条件付きの「エラー」クラスを追加できます。 errorsオブジェクトを確認することで、エラーを確認できます。
また、touchedプロパティをチェックして、エラーメッセージを表示する前に、ユーザーが電子メール入力を操作したかどうかを確認することもできます。
src / ValidatedLoginForm.js
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
className={errors.email && touched.email && "error"}
/>
最後に、エラーがある場合は、ユーザーに表示します。
メールフィールドの最終結果は次のようになります。
src / ValidatedLoginForm.js
<label htmlFor="email">Email</label>
<input
id="email"
name="email"
type="text"
placeholder="Enter your email"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
className={errors.email && touched.email && "error"}
/>
{errors.email && touched.email && (
<div className="input-feedback">{errors.email}</div>
)}
パスワードフィールドへのレンダリングプロップの適用
次に、パスワードで同じことを行う必要があります。 これらの手順は、電子メールに似ています。
パスワードフィールドの最終結果は次のようになります。
src / ValidatedLoginForm.js
<label htmlFor="password">Password</label>
<input
id="password"
name="password"
type="password"
placeholder="Enter your password"
value={values.password}
onChange={handleChange}
onBlur={handleBlur}
className={errors.password && touched.password && "error"}
/>
{errors.password && touched.password && (
<div className="input-feedback">{errors.password}</div>
)}
ステップ7—検証のテスト
フォームが完成したので、テストする準備が整いました。 何も入力せずにボタンをクリックすることから始めることができます。 検証メッセージが表示されます。
これで、メッセージのテストをより具体的にすることができます。 これを行うには、ページを更新してください。 メール入力の内側をクリックしますが、何も入力しないでください。
次に、入力から離れてクリックします。 Requiredメッセージがポップアップ表示されます。 このメッセージは、ページの読み込み時に自動的にポップアップ表示されないことに注意してください。 ユーザーが入力を操作した後にのみエラーメッセージを表示したい。
次に、入力を開始します。 メールが無効であるというメッセージが表示されます。
有効なメールアドレスを入力して、エラーメッセージが消えるのを確認してください。
ここで、パスワードについても同じようにします。 入力をクリックしてから離れると、必要なメッセージが表示されます。
次に、入力を開始すると、長さの検証が表示されます。
次に、数字を含まない8文字以上を入力すると、には数字のメッセージが含まれている必要があります。
最後に番号を追加すると、エラーメッセージが消えます。
結論
これで、FormikとYumを使用して、Reactで自動検証を行うフォームが作成されました。
Reactのその他のチュートリアルについては、Reactトピックページをご覧ください。