我正在使用shadcn的react-hook-form,我已经设法导航文档以获得我需要的输入和选择,但是我创建的onSubmit函数没有做任何事情。
有人知道为什么吗?
"use client";
import * as z from "zod";
import { SubmitHandler, useForm, UseFormRegister } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Input } from "./ui/input";
import ErrorMessage from "./ErrorMessage";
import { Button } from "./ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "./ui/Form";
import { Textarea } from "./ui/textarea";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import toast from "react-hot-toast";
type ReminderFormSchemaType = z.infer<typeof reminderFormSchema>;
export const reminderFormSchema = z.object({
title: z.string().min(1, { message: "Title required!" }),
description: z.string().max(160),
location: z.string(),
recurring: z.boolean(),
recurringDigit: z.string(),
recurringString: z.string(),
priority: z.string(),
});
const CreateReminder = () => {
const form = useForm<ReminderFormSchemaType>({
resolver: zodResolver(reminderFormSchema),
});
function onSubmit(data: ReminderFormSchemaType) {
toast.success("success!");
}
return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col w-full"
>
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>Title</FormLabel>
<FormControl>
<Input placeholder="Create a title..." {...field} />
</FormControl>
<FormDescription>
{form.formState.errors.title && (
<ErrorMessage
message={form.formState.errors.title?.message}
/>
)}
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Textarea
placeholder="Type your description here..."
{...field}
/>
</FormControl>
<FormDescription></FormDescription>
<FormMessage />
</FormItem>
)}
/>
<div className="flex flex-row justify-between items-center gap-x-3">
<FormField
control={form.control}
name="recurringDigit"
render={({ field }) => (
<FormItem className="flex flex-row items-center gap-x-3">
<FormLabel>Remind me every: </FormLabel>
<Select onValueChange={field.onChange} defaultValue="1">
<FormControl>
<SelectTrigger className="w-[100px]">
<SelectValue placeholder="1" />
</SelectTrigger>
</FormControl>
<SelectContent className="bg-lightbackground w-[100px]">
{Array.from(String(123456789)).map((value) => (
<SelectItem
key={value}
value={value}
className="cursor-pointer transition hover:bg-white hover:text-black"
>
{value}
</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)}
/>
<div className="flex-1">
<FormField
control={form.control}
name="recurringString"
render={({ field }) => (
<FormItem className="flex flex-row items-center flex-1 ">
<FormLabel></FormLabel>
<Select
onValueChange={field.onChange}
defaultValue="Minute(s)"
>
<FormControl>
<SelectTrigger className="flex-1 items-center">
<SelectValue placeholder="Minute(s)" />
</SelectTrigger>
</FormControl>
<SelectContent className="bg-lightbackground flex-1">
{["Day(s)", "Hour(s)", "Minute(s)"].map((value) => (
<SelectItem
key={value}
value={value}
className="cursor-pointer transition hover:bg-white hover:text-black"
>
{value}
</SelectItem>
))}
</SelectContent>
</Select>
</FormItem>
)}
/>
</div>
</div>
<div>
<FormField
control={form.control}
name="priority"
render={({ field }) => (
<FormItem className="flex flex-row items-center gap-x-3">
<FormLabel>Priority: </FormLabel>
<Select onValueChange={field.onChange} defaultValue="High">
<FormControl>
<SelectTrigger className="flex-1">
<SelectValue placeholder="High" />
</SelectTrigger>
</FormControl>
<SelectContent className="bg-lightbackground flex-1">
{["Low", "Medium", "High"].map((value) => (
<SelectItem
key={value}
value={value}
className="cursor-pointer transition hover:bg-white hover:text-black"
>
{value}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
</div>
<Button type="submit" className="bg-lightbackground my-3">
Submit
</Button>
</form>
</Form>
);
};
export default CreateReminder;
我收到了一个错误,我不明白这是否有用:
app-index.js:32 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. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
at input
at _c (webpack-internal:///(app-client)/./components/ui/input.tsx:13:11)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-slot/dist/index.mjs:46:23)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-slot/dist/index.mjs:20:23)
at eval (webpack-internal:///(app-client)/./components/ui/Form.tsx:124:14)
at div
at eval (webpack-internal:///(app-client)/./components/ui/Form.tsx:74:11)
at Controller (webpack-internal:///(app-client)/./node_modules/react-hook-form/dist/index.esm.mjs:544:37)
at FormField (webpack-internal:///(app-client)/./components/ui/Form.tsx:29:14)
at form
at FormProvider (webpack-internal:///(app-client)/./node_modules/react-hook-form/dist/index.esm.mjs:180:13)
at CreateReminder (webpack-internal:///(app-client)/./components/CreateReminder.tsx:53:75)
at div
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-primitive/dist/index.mjs:44:26)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-dismissable-layer/dist/index.mjs:44:42)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-slot/dist/index.mjs:46:23)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-slot/dist/index.mjs:20:23)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-primitive/dist/index.mjs:44:26)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-focus-scope/dist/index.mjs:32:19)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-dialog/dist/index.mjs:274:28)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-dialog/dist/index.mjs:206:102)
at $921a889cee6df7e8$export$99c2b779aa4e8b8b (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-presence/dist/index.mjs:28:22)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-dialog/dist/index.mjs:191:108)
at div
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-slot/dist/index.mjs:46:23)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-slot/dist/index.mjs:20:23)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-primitive/dist/index.mjs:44:26)
at eval (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-portal/dist/index.mjs:24:24)
at $921a889cee6df7e8$export$99c2b779aa4e8b8b (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-presence/dist/index.mjs:28:22)
at Provider (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-context/dist/index.mjs:47:28)
at $5d3850c4d0b4e6c7$export$dad7c95542bacce0 (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-dialog/dist/index.mjs:133:28)
at DialogPortal (webpack-internal:///(app-client)/./components/ui/dialog.tsx:25:11)
at _c2 (webpack-internal:///(app-client)/./components/ui/dialog.tsx:60:11)
at Provider (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-context/dist/index.mjs:47:28)
at $5d3850c4d0b4e6c7$export$3ddf2d174ce01153 (webpack-internal:///(app-client)/./node_modules/@radix-ui/react-dialog/dist/index.mjs:77:28)
at Modal (webpack-internal:///(app-client)/./components/Modal.tsx:15:11)
at div
at div
at div
at div
at Sidebar (webpack-internal:///(app-client)/./components/Sidebar.tsx:15:11)
at f (webpack-internal:///(app-client)/./node_modules/next-themes/dist/index.module.js:8:597)
at $ (webpack-internal:///(app-client)/./node_modules/next-themes/dist/index.module.js:8:348)
at Providers (webpack-internal:///(app-client)/./app/providers/Providers.tsx:7:11)
at body
at html
at RedirectErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect-boundary.js:73:9)
at RedirectBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect-boundary.js:81:11)
at NotFoundErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/not-found-boundary.js:51:9)
at NotFoundBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/not-found-boundary.js:59:11)
at ReactDevOverlay (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/react-dev-overlay/internal/ReactDevOverlay.js:66:9)
at HotReload (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:276:11)
at Router (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:90:11)
at ErrorBoundaryHandler (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:80:9)
at ErrorBoundary (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/error-boundary.js:106:11)
at AppRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/app-router.js:387:13)
at ServerRoot (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:154:11)
at RSCComponent
at Root (webpack-internal:///(app-client)/./node_modules/next/dist/client/app-index.js:171:11)
我在Dialog组件中使用了这个表单,它被有条件地呈现为:
"use client";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../components/ui/dialog";
import CreateReminder from "./CreateReminder";
import LoginForm from "./LoginForm";
import RegisterForm from "./RegisterForm";
import Subcategory from "./Subcategory";
import { Button } from "./ui/button";
import { IconType } from "react-icons";
const Modal: React.FC<{ label: string; icon: IconType }> = ({
label,
icon,
}) => {
return (
<Dialog>
<DialogTrigger className="w-full">
<Subcategory label={label} icon={icon} />
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle className="text-center py-2">{label}</DialogTitle>
<DialogDescription></DialogDescription>
</DialogHeader>
{label === "Login" ? (
<LoginForm />
) : label === "Register" ? (
<RegisterForm />
) : (
<CreateReminder />
)}
</DialogContent>
</Dialog>
);
};
export default Modal;
1条答案
按热度按时间5hcedyr01#
看起来你需要在定义表单时传递初始值,因为它们一开始是未定义的,然后当你在输入中输入时,它就不再是未定义的了。
当它从
undefined
变为'some value'
时,类型将从不受控变为受控