0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Reactで簡易コーポレートサイトを作成する #3 -バリデーションとビルド編-

Last updated at Posted at 2023-03-13

概要

react-hook-formを使ってバリデーションを実装します。
実装が完了したら、ビルドを実行してビルドファイルを作成してみます。

完成イメージ

000001.jpg 000010.jpg

#バリデーション実装

react-hook-formのインストール

react-hook-formというライブラリを使って、簡単にバリデーションを追加することができます。

npm install react-hook-form

宣言

Contact.jsを編集してreact-hook-formを適用していきます。
useForm()から必要なオブジェクトを宣言します。

キーワード 内容
useForm フォームを簡単に管理するためのカスタムフック
register フォームに適用したいルールをフックに登録するメソッド
handleSubmit バリデーションを通過したときにフォームのデータを受け取るメソッド
formState フォームの状態や情報をすべて持っている。そのためここではバリデーションエラーのメッセージを取得している
contact.js
    import React from "react";
    import './styles/Contact.css';
+   import { useForm } from "react-hook-form";

    const Contact = () => {
+       const {
+           register,
+           handleSubmit,
+           formState: { errors }
+       } = useForm();
        
コピペ用
const {
    register,
    handleSubmit,
    formState: { errors }
} = useForm();

onSubmit関数設定

送信ボタンがクリックされたときに実行されるonSubmit関数を設定します。
これは、APIにデータを送る想定で記述しています。

contact.js
    import React from "react";
    import './styles/Contact.css';
    import { useForm } from "react-hook-form";

    const Contact = () => {
        const {
            register,
            handleSubmit,
            formState:{errors}
        } = useForm();

+       const onSubmit = (data) => {
+           const api_url = 'apiのURL';
+
+           fetch(api_url, {
+               method: "post",
+               headers: {
+                   "Content-Type": "application/x-www-form-urlencoded",
+               },
+               body: encodeURI(`name=${data.name}&email=${data.email}&body=${data.body}`)
+           })
+               .then((response) => response.json())
+               .then((result) => alert(result.message))
+               .catch((error) => alert(error.message))
+       }
コピペ用
const onSubmit = (data) => {

    const api_url = 'apiのURL';

    fetch(api_url, {
        method: "post",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded",
        },
        body: encodeURI(`name=${data.name}&email=${data.email}&body=${data.body}`)
    })
        .then((response) => response.json())
        .then((result) => alert(result.message))
        .catch((error) => alert(error.message))
}

formタグでonSubmit()関数呼び出し

フォームが送信されると、作成した関数onSubmit()関数を呼び出すようにformタグにonSubmitを設定します。

contact.js
-      <form>
+      <form onSubmit={handleSubmit(onSubmit)}>

props追加

nameとemail、bodyフィールドに{...register(...)}というpropを追加します。
registerの中では、required属性とpattern属性、maxLength属性を指定します。
この2つにより、フィールドが正しくない場合にエラーを表示することができます。
それぞれの記述するとこのようになります。

contact.js(formのみ抜粋)
<form onSubmit={handleSubmit(onSubmit)}>
    <div className="form_group">
        <label>お名前</label>
        <input type="text" id="name" {...register("name", { required: "お名前は必須です。" })} />
        <span className="form_error" id="name_error">お名前は必須です</span>
    </div>
    <div className="form_group">
        <label>email</label>
        <input type="email" id="email" {...register("email", {
            required: "emailは必須です。",
            pattern: {
                value: /^[a-z0-9.]+@[a-z]+\.[a-z]+$/,
                message: "emailの形式で入力してください。"
            }
        })} />
        <span className="form_error" id="email_error">emailは必須かつemailの形式で入力してください</span>
    </div>
    <div className="form_group">
        <label>お問合せ内容</label>
        <textarea id="body" rows={4} {...register("body", {
            required: "お問合わせ内容は必須です。",
            maxLength: {
                value: 10,
                message: "10文字以下で入力してください。"
            }
        })}></textarea>
        <span className="form_error" id="body_error">お問合せ内容は必須かつ1文字以上10文字以下で入力してください</span>
    </div>
    <button className="submit_btn" id="submit_btn">送信</button>
</form>

次に、エラーメッセージを動的に表示するようにコードを編集します。
各エラーメッセージを下記の様に{errors.name && 左の条件にマッチした場合の動作}を使ってエラーメッセージがあれば表示するようにします。

contact.js

    <form onSubmit={handleSubmit(onSubmit)}>
        <div className="form_group">
            <label>お名前</label>
            <input type="text" id="name" {...register("name", { required: "お名前は必須です。" })} />
-           <span className="form_error">お名前は必須です</span>
+           {errors.name && <span className="form_error">{errors.name.message}</span>}
        </div>
        <div className="form_group">
            <label>email</label>
            <input type="email" id="email" {...register("email", {
                required: "emailは必須です。",
                pattern: {
                    value: /^[a-z0-9.]+@[a-z]+\.[a-z]+$/,
                    message: "emailの形式で入力してください。"
                }
            })} />
-           <span className="form_error hidden" id="email_error">emailは必須かつemailの形式で入力してください</span>
+           {errors.email && <span className="form_error">{errors.email.message}</span>}
        </div>
        <div className="form_group">
            <label>お問合せ内容</label>
            <textarea id="body" rows={4} {...register("body", {
                required: "お問合わせ内容は必須です。",
                maxLength: {
                    value: 10,
                    message: "10文字以下で入力してください。"
                }
            })}></textarea>
-            <span className="form_error hidden" id="body_error">お問合せ内容は必須かつ1文字以上10文字以下で入力してください</span>
+           {errors.body && <span className="form_error">{errors.body.message}</span>}
        </div>
        <button className="submit_btn" id="submit_btn">送信</button>
    </form>

最終的なコード

最終的なコードはこのようになっています。

contact.js
import React from "react";
import './styles/Contact.css';
import { useForm } from "react-hook-form";

const Contact = () => {
    const {
        register,
        handleSubmit,
        formState: { errors }
    } = useForm();

    const onSubmit = (data) => {

        const api_url = 'apiのURL';

        fetch(api_url, {
            method: "post",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded",
            },
            body: encodeURI(`name=${data.name}&email=${data.email}&body=${data.body}`)
        })
            .then((response) => response.json())
            .then((result) => alert(result.message))
            .catch((error) => alert(error.message))
    }
    return (
        <main className="contact_form">
            <h2>お問合せ</h2>
            <form onSubmit={handleSubmit(onSubmit)}>
                <div className="form_group">
                    <label>お名前</label>
                    <input type="text" id="name" {...register("name", { required: "お名前は必須です。" })} />
                    {errors.name && <span className="form_error">{errors.name.message}</span>}
                </div>
                <div className="form_group">
                    <label>email</label>
                    <input type="email" id="email" {...register("email", {
                        required: "emailは必須です。",
                        pattern: {
                            value: /^[a-z0-9.]+@[a-z]+\.[a-z]+$/,
                            message: "emailの形式で入力してください。"
                        }
                    })} />
                    {errors.email && <span className="form_error">{errors.email.message}</span>}
                </div>
                <div className="form_group">
                    <label>お問合せ内容</label>
                    <textarea id="body" rows={4} {...register("body", {
                        required: "お問合わせ内容は必須です。",
                        maxLength: {
                            value: 10,
                            message: "10文字以下で入力してください。"
                        }
                    })}></textarea>
                    {errors.body && <span className="form_error">{errors.body.message}</span>}
                </div>
                <button className="submit_btn" id="submit_btn">送信</button>
            </form>
        </main >
    )
}
export default Contact;

保存して動作確認をします。
000010.jpg

ビルドする

Reactで作成したファイルを公開するためにはビルドをする必要があります。

ビルドとはざっくり言うと人間にわかりやすく書いた言語をコンピューターが解釈しやすい言語に変換する作業という感じです。

外部に公開するときはbuildの中身をサーバにアップロードすればいいのですが、reactの仕組み上、DriveToWeb(GoogleDriveやMicrosft OnDriveにアップロードして公開できるサービス)では動作しないので、各環境にわせて設定する必要があります。(今後、この手順を公開するかもしれません)

Reactのビルドコマンドは以下のとおりです。
react-websiteフォルダにいることを確認して下記を実行します。

npm run build

ビルドが完了すると、buildというフォルダが生成されています。

000020.jpg

確認する

いままでは、開発サーバで確認していましたが、ビルドしたファイルが動くかどうかを確認していきたいと思います。

npm install -g serve
serve -s build

実行すると、サーバが起動します。
000030.jpg
開発サーバと同じポートで起動するので確認しても、開発サーバとの差がわかりにくいですが、この状態で起動しているのはbuild後のファイルです。

関連コンテンツ

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?