1
1

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 customHooks を利用してロジックとUIを切り離すまでをやってみた(2/5)〜ロジックの作成〜

Last updated at Posted at 2021-11-27

はじめに

React customHooks を利用してロジックとUIを切り離すまでをやってみたシリーズ

今回は、Create処理をcustomHooksとして切り出すための実装について書きます。

これまで

Hasuraにユーザーのデータと仮定してデータを作成し

データを外部APIとして取得できるようにして、Next.js(apollo)を使って、クエリやミューテーションできるようにしました

Hasuraから取得したユーザーデータの一覧ページと詳細ページを作りながら、SGISRを学んできました

このシリーズの目次

最終的なゴール

以下のような構成のアプリを作ることです。

スクリーンショット 2021-10-18 17.27.41.png

目的(最終的なゴールを達成する)

  • 仕事で使っている技術のキャッチアップと復習
  • 使う可能性がある技術の理解度向上

customHooks作成に必要なファイルを作成

components/
hooks/
└── useCreateForm.ts
pages/

customHooks作成

モジュールのimport

hooks/useCreateForms.ts
import { useState, ChangeEvent, FormEvent } from 'react'
import { useMutation } from '@apollo/client' // apolloを用いた通信処理
import { CREATE_USER } from '../queries/queries' // クエリコマンド
import { CreateUserMutation } from '../types/generated/graphql' // クエリコマンドに対応したデータ型

カスタムフックの定義

hooks/useCreateForms.ts

export const useCreateForm = () => {}

2つのuseStateの定義

hooks/useCreateForms.ts

export const useCreateForm = () => {
  const [text, setText] = useState('')
  const [username, setUsername] = useState('')
}

create処理を実装

前作ったやつをそのまま持ってきただけ

hooks/useCreateForms.ts

export const useCreateForm = () => {
  const [text, setText] = useState('')
  const [username, setUsername] = useState('')
  const [insert_users_one] = useMutation<CreateUserMutation>(CREATE_USER, {
      update(cache, { data: { insert_users_one } }) {
        const cacheId = cache.identify(insert_users_one)
        cache.modify({
          fields: {
            users(existingUsers, { toReference }) {
              return [toReference(cacheId), ...existingUsers]
            },
          },
        })
      },
    })
  }

これでユーザーの新規作成処理が実装できました。

input要素を入力したときのイベント処理の実装

hooks/useCreateForms.ts

export const useCreateForm = () => {
  const [text, setText] = useState('')
  const [username, setUsername] = useState('')
  const [insert_users_one] = useMutation<CreateUserMutation>(CREATE_USER, {
      update(cache, { data: { insert_users_one } }) {
        const cacheId = cache.identify(insert_users_one)
        cache.modify({
          fields: {
            users(existingUsers, { toReference }) {
              return [toReference(cacheId), ...existingUsers]
            },
          },
        })
      },
    })
  }
  const handleTextChange = (e: ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value)
  }

引数はイベント要素を受け取るようにして、setText()だけする処理にしています。

ユーザー名を変える処理の実装

hooks/useCreateForms.ts

export const useCreateForm = () => {
  const [text, setText] = useState('')
  const [username, setUsername] = useState('')
  const [insert_users_one] = useMutation<CreateUserMutation>(CREATE_USER, {
      update(cache, { data: { insert_users_one } }) {
        const cacheId = cache.identify(insert_users_one)
        cache.modify({
          fields: {
            users(existingUsers, { toReference }) {
              return [toReference(cacheId), ...existingUsers]
            },
          },
        })
      },
    })
  }
  const handleTextChange = (e: ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value)
  }
  const usernameChange = (e: ChangeEvent<HTMLInputElement>) => {
    setUsername(e.target.value)
  }

submitしたときの処理の実装

hooks/useCreateForms.ts

export const useCreateForm = () => {
  const [text, setText] = useState('')
  const [username, setUsername] = useState('')
  const [insert_users_one] = useMutation<CreateUserMutation>(CREATE_USER, {
      update(cache, { data: { insert_users_one } }) {
        const cacheId = cache.identify(insert_users_one)
        cache.modify({
          fields: {
            users(existingUsers, { toReference }) {
              return [toReference(cacheId), ...existingUsers]
            },
          },
        })
      },
    })
  }
  const handleTextChange = (e: ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value)
  }
  const usernameChange = (e: ChangeEvent<HTMLInputElement>) => {
    setUsername(e.target.value)
  }
  const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
      e.preventDefault()
      try {
        await insert_users_one({
          variables: {
            name: username,
          },
        })
      } catch (err) {
        alert(err.message)
      }
      setUsername('')
    }

関数handleSubmitが実行されたら

非同期で、関数insert_users_oneが実行されてユーザー情報を{}オブジェクトの中に入れて送っています。

非同期処理が成功・失敗にかかわらず終わったら、ユーザーネームを空文字をsetStateしています(初期化)。

最終的な実装結果

クリックすると実際のコードが見れます
import { useState, ChangeEvent, FormEvent } from 'react'
import { useMutation } from '@apollo/client'
import { CREATE_USER } from '../queries/queries'
import { CreateUserMutation } from '../types/generated/graphql'

export const useCreateForm = () => {
  const [text, setText] = useState('')
  const [username, setUsername] = useState('')
  const [insert_users_one] = useMutation<CreateUserMutation>(CREATE_USER, {
    update(cache, { data: { insert_users_one } }) {
      const cacheId = cache.identify(insert_users_one)
      cache.modify({
        fields: {
          users(existingUsers, { toReference }) {
            return [toReference(cacheId), ...existingUsers]
          },
        },
      })
    },
  })
  const handleTextChange = (e: ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value)
  }
  const usernameChange = (e: ChangeEvent<HTMLInputElement>) => {
    setUsername(e.target.value)
  }
  const printMsg = () => {
    console.log('Hello')
  }
  const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    try {
      await insert_users_one({
        variables: {
          name: username,
        },
      })
    } catch (err) {
      alert(err.message)
    }
    setUsername('')
  }
  return {
    text,
    handleSubmit,
    username,
    usernameChange,
    printMsg,
    handleTextChange,
  }
}

最終的に作った関数をreturnしたり、検証用の関数なども入れてます。

まとめ

今回は、Create処理をcustomHooksとして切り出すための実装について書きました。

次回

customHooksを利用してロジックとUIを切り離すまでのうち、ロジック作成はできたので、UI部分となるコンポーネント作成をしていきます。

アウトプット100本ノック実施中

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?