实现React的Formik

首先

按照标题,我们将使用React来实现Formik。

重要的事项

・进行验证检查。
・如果必填项未填写,则发送按钮将被禁用。
・点击发送按钮后,将进行POST通信。

实际输出

スクリーンショット 2023-11-01 23.17.52.png

 

├── src
│   ├── App.tsx
│   ├── Form
│   │   ├── Field.tsx
│   │   ├── UserFormFileds.tsx
│   │   ├── const.ts
│   │   ├── hooks.ts
│   │   ├── index.tsx
│   │   ├── types.ts
│   │   └── validation.ts
│   ├── api
│   │   └── api.ts
│   ├── index.tsx
│   └── logo.svg

编程

import React from 'react';
import { UserForm } from './Form';
import { useMyFormik } from './Form/hooks';
import { UserFormFields } from './Form/UserFormFileds';

function App() {
  // Form情報を取得
  const formik = useMyFormik();
  return (
    <div>
      <h1>Formikサンプル</h1>
      <UserForm formik={formik}>
        <UserFormFields formik={formik} />
      </UserForm>
    </div>
  );
}

export default App;
import { FormikProps } from 'formik';
import React from 'react';
import { UserFormValues } from './types';

export const UserForm: React.FC<UserFormProps> = (props) => {
  const { formik, children } = props;
  return (
    <form onSubmit={formik.handleSubmit}>
      {children}
      <button type="submit" disabled={!formik.isValid}>
        送信
      </button>
    </form>
  );
};

type UserFormProps = {
  formik: FormikProps<UserFormValues>; // UserFormValuesは入ってくる型を定義
  children: React.ReactNode;
};

import React from 'react';
import { FormikProps } from 'formik';
import { UserFormValues } from './types';
import { Field } from './Field';

type UserFormFieldsProps = {
  formik: FormikProps<UserFormValues>;
};

export const UserFormFields: React.FC<UserFormFieldsProps> = ({ formik }) => {
  return (
    <div>
      <Field formik={formik} fieldName="name" label="名前" type="text" />
      <Field
        formik={formik}
        fieldName="email"
        label="メールアドレス"
        type="email"
      />
    </div>
  );
};

import React from 'react';
import { FormikProps } from 'formik';
import { UserFormValues } from './types';

type FieldProps = {
  formik: FormikProps<UserFormValues>;
  fieldName: keyof UserFormValues; // keyofでUserFormValuesのプロパティ名を取得
  label: string;
  type: string;
};

export const Field: React.FC<FieldProps> = ({
  formik,
  fieldName,
  label,
  type,
}) => {
  const fieldError = formik.errors[fieldName];
  const fieldValue = formik.values[fieldName];
  const fieldTouched = formik.touched[fieldName];

  return (
    <div>
      <label htmlFor={fieldName}>{label}</label>
      <input
        type={type}
        id={fieldName as string}
        name={fieldName as string}
        onChange={formik.handleChange}
        onBlur={formik.handleBlur}
        value={fieldValue}
      />
      {fieldTouched && fieldError && <div>{fieldError}</div>}
    </div>
  );
};

import { useFormik } from 'formik';
import { useEffect } from 'react';
import { postApi } from '../api/api';
import { validationSchema } from './validation';
import { UserInitialValues } from './const';

export function useMyFormik() {
  const formik = useFormik({
    initialValues: UserInitialValues,
    validationSchema,
    onSubmit: async (values) => {
      try {
        const response = await postApi({
          title: values.name, // 名前をタイトルとして使用
          body: values.email, // メールアドレスを本文として使用
          userId: 1, // ユーザーIDを適切に設定
        });
        // レスポンスをコンソールに出力
        console.log('APIレスポンス:', response.data);
      } catch (error) {
        console.error('APIエラー:', error);
      }
    },
  });

  useEffect(() => {
    formik.validateForm(); // フォームが最初にロードされたときにバリデーションを実行
  }, []); // 空の依存リストを指定して一度だけ実行されるように

  return formik;
}

export const UserInitialValues = {
  name: '',
  email: '',
};
export type UserFormValues = {
    name: string;
    email: string;
};
import * as Yup from 'yup';

export const validationSchema = Yup.object({
  name: Yup.string().required('名前は必須項目です'),
  email: Yup.string()
    .email('有効なメールアドレスを入力してください')
    .required('メールアドレスは必須項目です'),
});
import axios from "axios"


const apiUrl = "https://jsonplaceholder.typicode.com/posts";

export const postApi = async (payload:any) => {
    const response = await axios.post(apiUrl, payload);
    return response;
}

Formik中的困难之一是useFormik。我不知道onSubmit到底在什么时候被触发。虽然它在提交时被触发,但如果没有实施前端部分,我不知道它在哪里被使用。在上面的示例实现中,它在提交时被触发。

      <button type="submit" disabled={!formik.isValid}>
        送信
      </button>
bannerAds