2021/09/26

非同期処理を制御してお問い合わせフォーム送信後の挙動をいい感じに作る。

@ 酒井悠宇

今回は題の通り、非同期処理を制御してサイトのお問い合わせフォーム送信後の挙動を実装していきたいと思います。

実装を簡単に説明すると、microCMSに対してPOSTするapiをnext.jsのapiRoute機能を使って作って、それをフォーム送信時に叩いています。

現時点でのapiと、それをを叩く部分のコードはこのような感じです。

api部分(pages/api/contact.ts )

import { NextApiResponse, NextApiRequest } from "next";

//contactの型定義
export type Contact = {
  text: string;
  email: string;
  number: string;
  body: string;
};

// /api/contactが叩かれた時に発火する関数
const contact = async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
  //POSTを行う際に使用するAPIキー
  const WRITE_API_KEY: string | undefined = process.env.WRITE_API_KEY;

  // APIキーがundefinedなら404ステータスコードを返却する。
  if (typeof WRITE_API_KEY === "undefined") {
    return res.status(404).end();
  }

  //フォームから送信されたデータをPOST
  await fetch(`https://[ここにはmicroCMSのドメインが入ります].microcms.io/api/v1/contact`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json; charset=utf-8",
      "X-WRITE-API-KEY": WRITE_API_KEY,
    },
    body: JSON.stringify(req.body),
  });
};

export default contact;


apiを叩く部分(フォームのsubmitイベント時に走らせる)

  //フォーム送信時に走る非同期関数
  const onSubmit = async (contact: Contact) => {//contactにフォームに入力された値がオブジェクト形式で入ってくる
    console.log(contact);

    // apiを叩く
    await fetch("/api/contact", {
      method: "POST",
      headers: {
        "Content-Type": "application/json; charset=utf-8",
      },
      //jsonデータを生成
      body: JSON.stringify(contact),
    });
  };


現時点では、「送信ボタンを押すと問題なくmicroCMSにPOSTされるけど、POSTされた後の挙動がなにもないので本当にフォームが送信されているのかどうかがわかりづらい」みたいな感じです。

これから非同期処理の制御方法を学んでその辺をいい感じに実装していきたいと思います。

---

実装方法


いい感じに実装できたのでやり方まとめまーす

コードは以下のような感じになりました。

api部分(pages/api/contact.ts )

import { NextApiResponse, NextApiRequest } from "next";

//contactの型定義
export type Contact = {
  text: string;
  email: string;
  number: string;
  category: string;
  body: string;
};

// /api/contactが叩かれた時に発火する関数
const contact = async (req: NextApiRequest, res: NextApiResponse) => {
  //POSTを行う際に使用するAPIキー
  const WRITE_API_KEY: string | undefined = process.env.WRITE_API_KEY;

  // APIキーがundefinedなら404ステータスコードを返却する。
  if (typeof WRITE_API_KEY === "undefined") {
    return res.status(404).end();
  }

  //フォームから送信されたデータをPOST
  await fetch(`https://masumi-ando.microcms.io/api/v1/contact`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json; charset=utf-8",
      "X-WRITE-API-KEY": WRITE_API_KEY,
    },
    //jsonデータを生成
    body: JSON.stringify(req.body),
  });
  res.end();
};

export default contact;


お問い合わせフォームのsubmitイベント時に叩くapiですね。
async/awaitでfetchメソッドの完了を待って、正しく完了したらres.end();でPromiseを返しています。

apiを叩く部分(フォームのsubmitイベント時に走らせる)

  //フォーム送信時に走る非同期関数
  const onSubmit = async (contact: Contact) => {
    //送信ボタンにローディングアニメーションを表示して押せないようにする
    setIsLoading(true);
    //microCMSにPOSTするapiを叩く
    await fetch("/api/contact", {
      method: "POST",
      headers: {
        "Content-Type": "application/json; charset=utf-8",
      },
      //jsonデータを生成
      body: JSON.stringify(contact),
    })
      //成功時
      .then(() => {
        //フォームを非表示に
        setIsOpen(false);
        //送信成功のメッセージを表示
        setMessage(true);
      })
      //失敗時
      .catch(() => {
        setIsOpen(false);
        //送信失敗のメッセージを表示
        setMessage(false);
      });
  };


お問い合わせフォームのsubmitイベント時に走る関数ですね。
awaitで叩いたapiがpromiseを返すのを待っています。
.then.catchで成功した場合と失敗した場合の挙動を実装しています。

---

今まではasync/awaitの使い所とかがあまりわからなくて難しいなーて感じだったんですけど、今回実際に非同期処理をいい感じに制御して機能を実装したことでいい感じに理解できたので良かったです。

最後までごらんいただきありがとうございました!

© 2021 powerd by UnReact