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?

【Vite×React×Nest.js】状態管理ライブラリ「Zustand」を使ってユーザー登録画面のクリアボタンを実装

Posted at

Blue, Orange and Grey Illustrated Ethical Hacking Toutube Thumbnail   (1).png

今回は、状態管理ライブラリ「Zustand」を使ってデータを管理する方法について記載します。

サンプル

ユーザー申請画面で値を入力して、「クリア」ボタンを押下すると、
image.png
入力値がクリアされます。
image.png

前回記事の続きとなります。

Zustand公式サイト

Zustandライブラリをインストール

下記のコマンドでzustandをインストールします。

npm install zustand

実装方針

1.Zustand ストアを作成

フォームの値を Zustand に保存・更新・クリアできるようにする。

2.useForm reset()Zustandclear()を組み合わせる

クリアボタン押下で…
■Zustand の値もクリア
■フォーム UI もクリア
ができるようにする。

3.useAdminUserStore.tsを追加

src/store/useAdminUserStore.tsを新規作成します。

src/store/useAdminUserStore.ts
import { create } from 'zustand';

type InputAdminUser = {
  userName: string;
  userEmail: string;
  userPassword: string;
  adminUserCheck: boolean;
};

type AdminUserStore = {
  form: InputAdminUser;
  setForm: (data: Partial<InputAdminUser>) => void;
  clearForm: () => void;
};

export const useAdminUserStore = create<AdminUserStore>((set) => ({
  form: {
    userName: '',
    userEmail: '',
    userPassword: '',
    adminUserCheck: false,
  },
  setForm: (data) =>
    set((state) => ({
      form: { ...state.form, ...data },
    })),
  clearForm: () =>
    set({
      form: {
        userName: '',
        userEmail: '',
        userPassword: '',
        adminUserCheck: false,
      },
    }),
}));

4.ユーザー申請フォームsrc/pages/admin_user/sign-up/page.tsxを修正

src/pages/admin_user/sign-up/page.tsx
import { useNavigate } from 'react-router-dom'; //ページ遷移用モジュール
import { useForm } from 'react-hook-form';
import { useAdminUserStore } from '../../../store/useAdminUserStore'; //状態管理用

type InputAdminUser = {
  userName: string;
  userEmail: string;
  userPassword: string;
  adminUserCheck: boolean;
};

export const AdminUserSignUpForm = () => {
  // useNavigateモジュールを定義
  const navigate = useNavigate();

  // Zustand Store
  const { form, setForm, clearForm } = useAdminUserStore();

  // トップページ戻るボタンクリック時の処理
  const clickBakToTopPage = () => {
    navigate('/');
  };

  const {
    register,
    handleSubmit,
    reset,
    //formState: { errors },
  } = useForm<InputAdminUser>({ defaultValues: form });

  // 確認画面へ遷移する処理
  const gotoConfirm = (data: InputAdminUser) => {
    setForm(data); // Zustand に保管
    navigate('/admin_user/sign-up-confirm', {
      state: data,
    });
  };

  // クリア処理
  const handleClear = () => {
    clearForm(); // Zustand の値クリア
    reset(); // react-hook-form の UI もクリア
  };

  return (
    <div className="flex justify-center items-center h-screen">
      <div className="w-full max-w-md">
        <form
          onSubmit={handleSubmit(gotoConfirm)}
          className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
        >
          <div className="mb-4">
            <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="adminUserName">
              ユーザ名
            </label>
            <input
              {...register('userName', { required: true })}
              type="text"
              className="shadow appearance-none border rounded w-full py-2 px-3 mb-4 text-gray-700 focus:outline-none focus:shadow-outline"
              placeholder="ユーザ名"
            />
            <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="adminUserEmail">
              メールアドレス
            </label>
            <input
              {...register('userEmail', { required: true })}
              type="email"
              className="shadow appearance-none border rounded w-full py-2 px-3 mb-4 text-gray-700 focus:outline-none focus:shadow-outline"
              placeholder="user@example.com"
            />
             
            <label
              className="block text-gray-700 text-sm font-bold mb-2"
              htmlFor="adminUserPassword"
            >
              パスワード
            </label>
             
            <input
              {...register('userPassword', { required: true })}
              type="password"
              className="shadow appearance-none border rounded w-full py-2 px-3 mb-4 text-gray-700 focus:outline-none focus:shadow-outline"
            />
            <label className="block text-gray-700 text-sm font-bold mb-2" htmlFor="adminUserCheck">
              管理者
            </label>
            <input {...register('adminUserCheck')} type="checkbox" />
            <div className="flex items-center justify-between">
              <button
                type="submit"
                className="bg-blue-500 hover:bg-blue-700 font-bold text-white rounded px-4 py-2 mr-2 cursor-pointer"
              >
                確認画面へ進む
              </button>
              <button
                type="button"
                className="bg-green-500 hover:bg-green-700 font-bold text-white rounded px-4 py-2 mr-2 cursor-pointer"
                onClick={clickBakToTopPage}
              >
                ホームへ戻る
              </button>

              <button
                type="button"
                className="bg-gray-500 hover:bg-gray-700 font-bold text-white rounded px-4 py-2 mr-4 cursor-pointer"
                onClick={handleClear}
              >
                クリア
              </button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
};

✅ これでできること

✔ フォーム入力は Zustand に保存

setForm() によってフォーム値が常に状態管理される。

✔ クリアボタンでZustand の値が空に戻る

⇒reset() により UI の入力欄もクリアされる

✔ 確認画面に遷移しても戻っても値を保持できる

サイト

tailwindcssで要素を画面の中央に配置する方法

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?