【问题标题】:Why can I not type into the input fields using Formik and Yup?为什么我不能使用 Formik 和 Yup 在输入字段中输入内容?
【发布时间】:2022-10-06 02:30:46
【问题描述】:

当我尝试输入输入字段时,没有出现任何字母。我实际上有一个使用类似代码的登录页面工作正常,所以我现在不知道为什么它不能在这个页面上工作。我认为这可能与我定义 initialValues 的方式有关,因为它们是嵌套的,但是我已经尝试将它们写成不嵌套的并且它不起作用。

import { NextPage } from \'next\'
import { Prisma } from \'@prisma/client\';
import { FormikValues, useFormik, validateYupSchema } from \'formik\';
import * as Yup from \'yup\'
import { useState } from \'react\';
import { useRouter } from \'next/router\';
import { useSession } from \'next-auth/react\';

const Register: NextPage = () => {

  const router = useRouter()
  const { data: session } = useSession()
  if (session) {
    router.push(\'/\')
  }

  const [error, setError] = useState(\'\')

  const handleRegister = async ({
    userInfo: {
      email,
      password
    },

    companyInfo: {
      companyName,
      gender,
      firstName,
      lastName,
      street,
      houseNumber,
      postcode,
      city,
      country,
      countryCode,
      callNumber,
      emailAddress,
      website,
      socials
    } }: FormikValues) => {

    const userInfo: Prisma.UserCreateInput = {
      email,
      hashedPassword: password //Not hashed yet!
    }

    const companyInfo: Prisma.CompanyCreateInput = {
      name: companyName,
      gender,
      firstName,
      lastName,
      street,
      houseNumber,
      postcode,
      city,
      country,
      countryCode,
      callNumber,
      emailAddress,
      website,
      socials,
      companyUser: {
        connect: { id: \'\' }
      }
    }

    const registerData: FormikValues = {
      userInfo,
      companyInfo
    }

    const registerDataJSON = JSON.stringify(registerData)

    const endpoint: RequestInfo = \'/api/register/register\'
    const options: RequestInit = {
      method: \'POST\',
      headers: {
        \'Content-Type\': \'application/json\'
      },
      body: registerDataJSON
    }

    try {
      const response: Response = await fetch(endpoint, options)

      const url = response.headers.get(\'Location\')

      if (url) {
        window.location.href = url
      }
    } catch {
      setError(\'Register failed\')
    } finally {
      formik.setSubmitting(false)
    }
  }

  const formik = useFormik({
    initialValues: {
      userInfo: {
        email: \'\',
        password: \'\'
      },

      companyInfo: {
        companyName: \'\',
        gender: \'\',
        firstName: \'\',
        lastName: \'\',
        street: \'\',
        houseNumber: \'\',
        postcode: \'\',
        city: \'\',
        country: \'\',
        countryCode: \'\',
        callNumber: \'\',
        emailAddress: \'\',
        website: \'\',
        socials: \'\'
      }
    },
    validationSchema: Yup.object().shape({
      userInfo: Yup.object().shape({
        email: Yup.string()
          .required(\'email address is required\')
          .email(\'email address must be valid\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Email Address cannot include leading and trailing spaces\'),
        password: Yup.string()
          .required(\'Password address is required\')
          .min(8, \'Password must be at least 8 characters long\')
          .max(20, \'Password cannot be longer than 20 characters\')
          .matches(
            /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#\\$%\\^&\\*])/,
            \'Password must contain at least one number as well as one uppercase, lowercase and special character\'
          )
          .trim(\'Password cannot include leading and trailing spaces\')
          .matches(
            /^(?!.* )/,
            \'Password cannot contain whitespaces\'
          )
      }),
      companyInfo: Yup.object().shape({
        companyName: Yup.string()
          .strict(true)
          .required()
          .max(50, \'Company Name cannot be longer than 50 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Company Name cannot include leading and trailing spaces\'),
        gender: Yup.string()
          .strict(true)
          .required()
          .max(20, \'Gender cannot be longer than 20 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Gender cannot include leading and trailing spaces\'),
        firstName: Yup.string()
          .strict(true)
          .required()
          .max(50, \'First Name cannot be longer than 50 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'First Name cannot include leading and trailing spaces\'),
        lastName: Yup.string()
          .strict(true)
          .required()
          .max(50, \'Last Name cannot be longer than 50 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Last Name cannot include leading and trailing spaces\'),
        street: Yup.string()
          .strict(true)
          .required()
          .max(50, \'Street cannot be longer than 50 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Street cannot include leading and trailing spaces\'),
        houseNumber: Yup.string()
          .strict(true)
          .required()
          .max(10, \'House Number cannot be longer than 10 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Hpuse Number cannot include leading and trailing spaces\'),
        postcode: Yup.string()
          .strict(true)
          .required()
          .max(50, \'Postcode cannot be longer than 50 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Postcode cannot include leading and trailing spaces\'),
        city: Yup.string()
          .strict(true)
          .required()
          .max(58, \'City cannot be longer than 58 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'City cannot include leading and trailing spaces\'),
        country: Yup.string()
          .strict(true)
          .required()
          .max(56, \'Country cannot be longer than 56 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Country cannot include leading and trailing spaces\'),
        countryCode: Yup.string()
          .strict(true)
          .required()
          .max(10, \'Country Code cannot be longer than 10 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Country Code cannot include leading and trailing spaces\')
          .matches(
            /^(?!.* )/,
            \'Country Code cannot contain whitespaces\'
          ),
        callNumber: Yup.string()
          .strict(true)
          .required()
          .min(1, \'Call Number must be bigger than 0\')
          .max(20, \'Call Number cannot be longer than 20 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Country Code cannot include leading and trailing spaces\')
          .matches(
            /^(?!.* )/,
            \'Call Number cannot contain whitespaces\'
          ),
        emailAddress: Yup.string()
          .strict(true)
          .required()
          .email(\'Email Address must be valid\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Email Address cannot include leading and trailing spaces\')
          .matches(
            /^(?!.* )/,
            \'Email Address cannot contain whitespaces\'
          ),
        website: Yup.string()
          .strict(true)
          .required()
          .url(\'Website must be a URL\')
          .max(100, \'Website cannot be longer than 100 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Website cannot include leading and trailing spaces\')
          .matches(
            /^(?!.* )/,
            \'Website cannot contain whitespaces\'
          ),
        socials: Yup.string()
          .strict(true)
          .required()
          .max(100, \'Socials cannot be longer than 100 characters\')
          .transform((value) => value.replace(/\\s+/g, \' \').trim())
          .trim(\'Socials cannot include leading and trailing spaces\')
      })
    }),
    onSubmit: (values) => {
      handleRegister(values)
    }
  })

  return (
    <form onSubmit={formik.handleSubmit} noValidate>
      <h2>User Information</h2>

      <label>
        Email Address<span>*</span>
        <input
          name=\'email\'
          type=\'email\'
          value={formik.values.userInfo.email}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.userInfo?.email && formik.errors.userInfo?.email && <p>{formik.errors.userInfo.email}</p>}

      <label>
        Password<span>*</span>
        <input
          name=\'password\'
          type=\'password\'
          value={formik.values.userInfo.password}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.userInfo?.password && formik.errors.userInfo?.password && <p>{formik.errors.userInfo.password}</p>}

      <h2>Company Information</h2>

      <label>
        Company Name<span>*</span>
        <input
          name=\'companyName\'
          type=\'text\'
          value={formik.values.companyInfo.companyName}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.companyName && formik.errors.companyInfo?.companyName && <p>{formik.errors.companyInfo.companyName}</p>}

      <label>
        Gender<span>*</span>
        <input
          name=\'gender\'
          type=\'text\'
          list=\'genders\'
          value={formik.values.companyInfo.gender}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
        <datalist id=\'genders\'>
          <option>Female</option>
          <option>Male</option>
        </datalist>
      </label>
      {formik.touched.companyInfo?.gender && formik.errors.companyInfo?.gender && <p>{formik.errors.companyInfo.gender}</p>}

      <label>
        First Name<span>*</span>
        <input
          name=\'firstName\'
          type=\'text\'
          value={formik.values.companyInfo.firstName}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.firstName && formik.errors.companyInfo?.firstName && <p>{formik.errors.companyInfo.firstName}</p>}

      <label>
        Last Name<span>*</span>
        <input
          name=\'lastName\'
          type=\'text\'
          value={formik.values.companyInfo.lastName}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.lastName && formik.errors.companyInfo?.lastName && <p>{formik.errors.companyInfo.lastName}</p>}

      <label>
        Street<span>*</span>
        <input
          name=\'street\'
          type=\'text\'
          value={formik.values.companyInfo.street}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.street && formik.errors.companyInfo?.street && <p>{formik.errors.companyInfo.street}</p>}

      <label>
        House Number<span>*</span>
        <input
          name=\'houseNumber\'
          type=\'text\'
          value={formik.values.companyInfo.houseNumber}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.houseNumber && formik.errors.companyInfo?.houseNumber && <p>{formik.errors.companyInfo.houseNumber}</p>}

      <label>
        Postcode<span>*</span>
        <input
          name=\'postcode\'
          type=\'text\'
          value={formik.values.companyInfo.postcode}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.postcode && formik.errors.companyInfo?.postcode && <p>{formik.errors.companyInfo.postcode}</p>}

      <label>
        City<span>*</span>
        <input
          name=\'city\'
          type=\'text\'
          value={formik.values.companyInfo.city}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.city && formik.errors.companyInfo?.city && <p>{formik.errors.companyInfo.city}</p>}

      <label>
        Country<span>*</span>
        <input
          name=\'country\'
          type=\'text\'
          value={formik.values.companyInfo.country}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.country && formik.errors.companyInfo?.country && <p>{formik.errors.companyInfo.country}</p>}

      <label>
        Country Code<span>*</span>
        <input
          name=\'countryCode\'
          type=\'text\'
          value={formik.values.companyInfo.countryCode}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.countryCode && formik.errors.companyInfo?.countryCode && <p>{formik.errors.companyInfo.countryCode}</p>}

      <label>
        Call Number<span>*</span>
        <input
          name=\'callNumber\'
          type=\'text\'
          value={formik.values.companyInfo.callNumber}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.callNumber && formik.errors.companyInfo?.callNumber && <p>{formik.errors.companyInfo.callNumber}</p>}

      <label>
        Email Address<span>*</span>
        <input
          name=\'emailAddress\'
          type=\'email\'
          value={formik.values.companyInfo.emailAddress}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.emailAddress && formik.errors.companyInfo?.emailAddress && <p>{formik.errors.companyInfo.emailAddress}</p>}

      <label>
        Website
        <input
          name=\'website\'
          type=\'text\'
          value={formik.values.companyInfo.website}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.website && formik.errors.companyInfo?.website && <p>{formik.errors.companyInfo.website}</p>}

      <label>
        Socials
        <input
          name=\'socials\'
          type=\'text\'
          value={formik.values.companyInfo.socials}
          onChange={formik.handleChange}
          onBlur={formik.handleBlur}
        />
      </label>
      {formik.touched.companyInfo?.socials && formik.errors.companyInfo?.socials && <p>{formik.errors.companyInfo.socials}</p>}

      <button type=\'submit\' disabled={formik.isSubmitting}>Login</button>
      {formik.isSubmitting && <div>Loading...</div>}
      {!formik.isSubmitting && error && <div>{error}</div>}
    </form>
  )
}

export default Register

    标签: input next.js formik yup


    【解决方案1】:

    onChangesetFieldTouched 中使用Formik 的setFieldValue onBlur 事件。

    <input
      name="email"
      type="email"
      value={formik.values.userInfo.email}
      onChange={(e) => formik.setFieldValue("userInfo.email", e.target.value)}
      onBlur={() => formik.setFieldTouched("userInfo.email", true)}
    />
    

    Example codesandbox

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-01
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多