a little background

我正在使用shadcn UI库和Zod在我的Next.js Reaction应用程序中创建一些简单的表单. 输入类型为selecttext

The problem

我正在遵循shadcn文档,了解如何使用Zod和shadcn的UI组件设置表单,但当text输入的值发生更改时,我收到错误消息:

Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen.

Worth mentioning

该错误仅在更改text(用户名)输入值时出现.

此外,尽管出现错误,该表单仍工作正常.

What I've tried

我已经查找了错误,我发现答案是在{...field}之后添加valuedefaultValue,并使用useState('')挂钩的组合,这解决了错误,但现在它不允许我提交表格.

Code

'use client'
import {
    Form,
    FormControl,
    FormDescription,
    FormField,
    FormItem,
    FormLabel,
    FormMessage,
  } from "@/components/ui/form"
import { useForm } from 'react-hook-form'
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { toast } from "@/components/ui/use-toast"
import Link from "next/link"
import { Input } from "@/components/ui/input"
import { ReactNode, useState } from "react"
const FormSchema = z.object({
  email: z
    .string({
      required_error: "Please select an email to display.",
    })
    .email(),
    username: z.string(),
 
})

const ZodForm = () => {

  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
  })
  
  function onSubmit(data: z.infer<typeof FormSchema>) {
    console.log(data);
    
    toast({
      title: "You submitted the following values:",
      description: (
        <pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
          <code className="text-white">{JSON.stringify(data, null, 2)}</code>
        </pre>
      ),
    })
  }


  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <Select onValueChange={field.onChange} defaultValue={field.value}>
                <FormControl>
                  <SelectTrigger>
                    <SelectValue placeholder="Select a verified email to display" />
                  </SelectTrigger>
                </FormControl>
                <SelectContent>
                  <SelectItem value="m@example.com">m@example.com</SelectItem>
                  <SelectItem value="m@google.com">m@google.com</SelectItem>
                  <SelectItem value="m@support.com">m@support.com</SelectItem>
                </SelectContent>
              </Select>
              <FormDescription>
                You can manage email addresses in your{" "}
                <Link href="/examples/forms">email settings</Link>.
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name={'username'}
          render={({ field }) => (
            <FormItem>
              <FormLabel>Username</FormLabel>
              <FormControl>
                <Input placeholder="shadcn" {...field}  />
              </FormControl>
              <FormDescription>
                This is your public display name.
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
        <button type="submit">Submit</button>
      </form>
    </Form>
  )
}

export default ZodForm

推荐答案

之所以会发生这种情况,是因为您没有将defaultValues设置为useForm.

所以,defaultValues是没有定义的.

然后,当你使用<FormField />时,你可能会写成这样:

<FormField
  control={form.control}
  name="username"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Username</FormLabel>
      <FormControl>
        <Input {...field} />
      </FormControl>
      <FormDescription>This is your public display name.</FormDescription>
      <FormMessage />
    </FormItem>
  )}
/>

请注意这行<Input {...field} />

fieldrefvalueonChangeonBlurname的对象.

问题是value是由undefined初始化的,然后当你写任何字母时,它就从未定义变成了字符串.

您可以通过设置缺省值轻松地解决这个问题

useForm({
  defaultValues: {
    username: ""
  }
})

Reactjs相关问答推荐

全局上下文挂钩-替代不起作用

REACTJS:在Reaction中根据路由路径更改加载器API URL

未定义发送的数据无法在reactjs中找到原因

如何在我的 React 应用程序中仅显示我的 Register 组件

使用以Jest 的方式返回 Promise 的方法来模拟可构造的 API 类时出现问题

画布:用鼠标绘制形状时重新绘制整个画布会导致卡顿

如何在 ReactJS 中提交后删除 URL 中的查询参数

将 useState 设置为组件内部的值

如何在不重新加载页面的情况下加载新添加的数据?

如何保留我的下一个授权用户会话?所以我可以使用提供的 ID 在其他路由中获取数据

在复选框中react 检索选中的值

当从数组中删除数据时,UseEffect 不会重新渲染,仅在添加数据时才会重新渲染

React Native map 中的初始zoom 级别

React Native PermissionsAndroid 不包括 READ_MEDIA_IMAGES.如何解决这个问题?

调用 Statsig.updateUser 时 UI 不呈现

如何在 MUI 数据网格中的 renderCell 组件之间传递状态

Cypress - 在继续之前等待下一个按钮重新出现

如何在 React JS 上使文本中的单词可点击

如何在 react-router-dom v6 中实现监听功能?

在渲染不显示子元素之后,再次渲染时,子元素状态数据完全消失了.为什么会这样以及如何防止它发生?