gpt4 book ai didi

Error messages from react-hook-form with zod(来自带有Zod的Reaction-Hook-Form的错误消息)

转载 作者:bug小助手 更新时间:2023-10-27 19:54:47 31 4
gpt4 key购买 nike



I created a customer registration form, but all my "messages" from my "errors" are coming as required. Does anyone know what it could be? Something I set up wrong in zod or react-hook-form. Below I will leave the prints of the code.

我创建了一个客户注册表,但所有来自我的“错误”的“消息”都会按要求发送。有人知道这会是什么吗?我在Zod或Reaction-Hook-Form中设置的错误。下面我将留下代码的指纹。


This is my generic input component:

这是我的通用输入组件:


import { DetailedHTMLProps, InputHTMLAttributes } from 'react'

interface InputProps
extends DetailedHTMLProps<
InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
> {
label: string
error?: string
}

export const Input = ({ error, label, ...rest }: InputProps) => {
return (
<div className="flex flex-col">
<label
className="mb-2 block text-sm font-bold text-zinc-700"
htmlFor={rest.id}
>
{label}
</label>
<input
type="text"
className={`appearance-none rounded-md border border-zinc-300 px-3 py-2 leading-tight shadow-sm focus:border-zinc-500 focus:outline-none
${error ? 'border-red-500' : 'border-zinc-300'}`}
{...rest}
/>
{error && <span className="text-xs text-red-500">{error}</span>}
</div>
)
}


And here is where I created my schema and where I am using this generic input component inside the form:

这里是我创建schema的地方,也是我在表单中使用这个通用输入组件的地方:


import { Input } from '../Input'
import { Modal } from '../Modal'

import { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'

interface ClientRegistrationModalProps {
isOpen: boolean
onClose: () => void
}

const createUserFormSchema = z.object({
name: z
.string()
.min(2, 'Password must be at least 2 characters long')
.transform((name) =>
name
.trim()
.split(' ')
.map((word) => {
return word[0].toLocaleUpperCase().concat(word.substring(1))
})
.join(' '),
),
email: z
.string()
.email('Invalid e-mail format')
.nonempty('E-mail is required'),
birthdate: z.string().nonempty('Date of birth is mandatory'),
cpf: z.string().length(11, 'CPF mus have 11 digits'),
})

type CreateUserFormData = z.infer<typeof createUserFormSchema>

export const ClientRegistrationModal = ({
isOpen,
onClose,
}: ClientRegistrationModalProps) => {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
reset,
} = useForm<CreateUserFormData>({
mode: 'all',
resolver: zodResolver(createUserFormSchema),
})

// High-order function
function createUser(data: CreateUserFormData) {
console.log(data)
}

function resetForm() {
onClose()
reset()
}

console.log(errors)

return (
<Modal title="Cadastro de Cliente" isOpen={isOpen} onClose={resetForm}>
<form onSubmit={handleSubmit(createUser)}>
<div className="flex flex-col space-y-6">
<Input
label="Nome"
type="text"
id="name"
placeholder="Enter your name"
{...register('name')}
error={errors.name?.message}
/>

<Input
label="Email"
type="email"
id="email"
placeholder="Enter your e-mail"
{...register('email')}
error={errors.email?.message}
/>

<Input
label="Data de Nascimento"
type="date"
id="birthdate"
{...register('birthdate')}
error={errors.birthdate?.message}
/>

<Input
label="CPF"
type="text"
id="cpf"
placeholder="Enter your CPF"
{...register('cpf')}
error={errors.cpf?.message}
/>
</div>
<div className="mt-4 flex items-center justify-between">
<button
className="mt-4 rounded bg-green-500 px-4 py-2 font-bold text-white transition-all ease-in hover:bg-green-700"
type="submit"
>
Cadastrar
</button>
<button
type="reset"
className="mt-4 rounded bg-zinc-500 px-4 py-2 font-bold text-white transition-all ease-in hover:bg-zinc-700"
onClick={resetForm}
disabled={isSubmitting}
>
Cancelar
</button>
</div>
</form>
</Modal>
)
}

The problem here is, when I give console.log(errors), my errors are all as "Required", that is, they are not showing the error messages that I set inside my schema.

这里的问题是,当我给sole.log(错误)时,我的错误都是“必需的”,也就是说,它们没有显示我在模式中设置的错误消息。


I don't know what could be wrong and would like some help. Maybe it's some typing issue or something I configured wrong. I appreciate any help.

我不知道会出什么问题,我想要一些帮助。可能是打字有问题,也可能是我配置错了。我很感激你们的帮助。


Instead of using that:
name: z.string().min(2, 'The name needs at least 2 characters')

不使用:name:z.string().min(2,‘名称需要至少2个字符’)


I used this:
name: z.string().min(2,{ message: 'The name needs at least 2 characters' })

我使用的是:name:z.string().min(2,{Message:‘名称需要至少2个字符’})


But it didn't work.

但这并没有奏效。


更多回答
优秀答案推荐

Solution


I was facing the same problem and it had to do with a bad setup between my custom Input component and the {...register("name")} props. Try changing your input to the standard <input /> component and see if the game changes... it probably will.

我也面临着同样的问题,这与我的自定义输入组件和{...Register(“name”)}道具之间的错误设置有关。尝试将您的输入更改为标准的组件,并查看游戏是否发生变化...很可能会这样。


Honestly I have no idea why spreading the {...register("name")} is causing problems, but it is. Here's a fixed version of your component, all I did different was passing down the register function as a Prop and calling it inside the Input (Maybe you should rename the component to InputForm cus it's now a pretty specific component that only works with such function)

老实说,我不知道为什么传播{...注册(“姓名”)会导致问题,但它是。这是您的组件的固定版本,我所做的不同之处只是将注册函数作为一个道具传递并在输入中调用它(也许您应该将该组件重命名为InputForm,因为它现在是一个非常特定的组件,只与这样的函数一起工作)


I also decided to pass down the name as a prop so we can properly call register. For convenience we can also infer the error messages with the name prop.

我还决定将这个名称作为道具传递下去,这样我们就可以正确地调用注册。为方便起见,我们还可以使用名称Prop来推断错误消息。


import { type DetailedHTMLProps, type InputHTMLAttributes } from "react";
import {
type FieldErrors,
type FieldValues,
type Path,
type UseFormRegister,
} from "react-hook-form";

interface InputProps<FormData extends FieldValues>
extends DetailedHTMLProps<
InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
> {
label: string;
name: Path<FormData>;
register: UseFormRegister<FormData>;
errors: FieldErrors<FormData>;
}

export const Input = <FormData extends FieldValues>({
label,
name,
errors,
register,
...rest
}: InputProps<FormData>) => {
const error = errors?.[name]?.message as string | undefined;

return (
<div className="flex flex-col">
<label
className="mb-2 block text-sm font-bold text-zinc-700"
htmlFor={rest.id}
>
{label}
</label>
<input
type="text"
className={`appearance-none rounded-md border border-zinc-300 px-3 py-2 leading-tight shadow-sm focus:border-zinc-500 focus:outline-none
${error ? "border-red-500" : "border-zinc-300"}`}
{...rest}
{...register(name)}
/>
{error && <span className="text-xs text-red-500">{error}</span>}
</div>
);
};

Usage of the component


<Input
label="Nome"
type="text"
placeholder="Enter your name"
name="name"
errors={errors}
register={register}
/>

<Input
label="Email"
type="email"
name="email"
placeholder="Enter your e-mail"
errors={errors}
register={register}
/>
// ... and so forth

Here's the result:
enter image description here

结果如下:


Workaround


If you still want to keep you component that way, there's a workaround, you'll need to specify your message in more than one place.

如果您仍然想让组件保持这种方式,有一个解决办法,您需要在多个地方指定您的消息。


What's happening is that zod and react-hook-form generate different error messages depending on the situation, which is a great feature actually. So the error type that it is firing for you does not come from the message you've set in min() but from the z.string() part of the zod schema:

目前的情况是,Zod和Reaction-Hook-Form根据情况生成不同的错误消息,这实际上是一个很好的功能。因此,它为您触发的错误类型不是来自您在min()中设置的消息,而是来自Zod模式的z.string()部分:


  name: z
.string()
.min(2, 'Password must be at least 2 characters long')

So to fix that, let's specify a custom message for the required_error in the string()

因此,为了解决这个问题,让我们为字符串()中的REQUIRED_ERROR指定一个定制消息


  name: z
.string({ required_error: 'Passoword is required' })
.min(2, 'Password must be at least 2 characters long')

Now you'll have a better error message when the form is submitted with an empty name field.

现在,当表单提交时名称字段为空时,您会得到更好的错误消息。


For anyone facing a similar problem but not exactly this one, I recommend logging the error message that is coming from react-hook-form so you can investigate where your error is coming from, that's how I figured how to fix this problem.

对于任何面临类似问题但不完全是这个问题的人,我建议记录来自Reaction-Hook-Form的错误消息,这样您就可以调查错误来自哪里,这就是我如何解决这个问题的方法。


You can do that by passing a second parameter in the handleSubmit function and using that to log your error:

您可以通过在handleSubmit函数中传递第二个参数并使用该参数来记录错误:



const onFormError:SubmitErrorHandler<CreateUserFormData> = (e) => {
console.log(e)
}

// Pass down this function in the handleSubmit
<form onSubmit={handleSubmit(createUser, onFormError)}>


I faced the same problem when using zod with react-hook-form. Even though i added custom message in zod object but still im getting error message as Required. after searching through the net i found this article.

在使用带有反应挂钩形式的Zod时,我遇到了同样的问题。即使我在Zod对象中添加了自定义消息,但仍收到所需的错误消息。在网上搜索后,我找到了这篇文章。


In the article i found out this errors={errors["name"] && `${(errors["name"] as DeepMap<FieldValues, FieldError>).message}`}
and it worked for me

在这篇文章中,我发现了这个错误={Errors[“name”]&&`${(Errors[“name”]as DeepMap ).Message}`},这对我很有效


<Input
label="Nome"
type="text"
placeholder="Enter your name"
name="name"
errors={errors["name"] && `${(errors["name"] as DeepMap<FieldValues, FieldError>).message}`}
register={register}
/>

DeepMap is a package from react-hook-form

DeepMap是来自Reaction-Hook-Form的包


reference:
https://www.react-hook-form.com/ts/#FieldErrors

参考文献:https://www.react-hook-form.com/ts/#FieldErrors


更多回答

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com