我想使用 ShadCN 创建两个 Select 组件。我希望这些选择彼此之间具有依赖关系。
这意味着为类别选择值后,子类别的选择将相应地填充过滤后的数据。
这一步效果很好。
但是,当我单击提交表单时,类别好像是空值,我相信这是因为我在
onValueChange
事件中使用自定义句柄函数,而不是使用 field.onChange
。
我仍然没有掌握使用
Form
组件及其所有复杂性的窍门,所以我不明白如何使用自己的更改函数来处理事件,甚至不明白如何将这些组件作为可重用组件和避免干燥。
#... imports
export const TransactionForm = () => {
const [selectedCategory, setSelectedCategory] = useState<string>("");
const [selectedSubcategory, setSelectedSubcategory] = useState<string>("");
const [filteredSubcategories, setFilteredSubcategories] = useState<string[]>(
[]
);
const form = useForm<z.infer<typeof TransactionSchema>>({
resolver: zodResolver(TransactionSchema),
defaultValues: {
category: "",
subcategory: "",
},
});
const categories = [...dummyData.categories].map((item) => item.name);
const onSubmit = (values: z.infer<typeof TransactionSchema>) => {
console.log(values);
};
const handleCategoryChange = (category: string) => {
setSelectedCategory(category);
setSelectedSubcategory("");
console.log(category);
const categoryData = dummyData.categories.find(
(item) => item.name === category
);
if (categoryData) {
setFilteredSubcategories(categoryData.subcategories);
} else {
setFilteredSubcategories([]);
}
};
const handleSubcategoryChange = (subcategory: string) => {
setSelectedSubcategory(subcategory);
};
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<div className="space-y-4">
<FormField
control={form.control}
name="category"
render={({ field }) => (
<FormItem>
<FormLabel>Category:</FormLabel>
<Select
onValueChange={(value) => handleCategoryChange(value)}
defaultValue={field.value}
>
<FormControl>
<SelectTrigger className="w-[180px] h-[40px]">
<SelectValue placeholder="Category" />
</SelectTrigger>
</FormControl>
<SelectContent className="bg-white">
<SelectGroup>
<SelectLabel>Category</SelectLabel>
{categories.map((option, index) => (
<SelectItem key={index} value={option}>
{option}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</FormItem>
)}
/>
<FormField
control={form.control}
name="subcategory"
render={({ field }) => (
<FormItem>
<FormLabel>Subcategory:</FormLabel>
<Select
onValueChange={field.onChange}
defaultValue={field.value}
{...field}
>
<FormControl>
<SelectTrigger className="w-[180px] h-[40px]">
<SelectValue placeholder="Subcategory" />
</SelectTrigger>
</FormControl>
<SelectContent className="bg-white">
<SelectGroup>
<SelectLabel>Subcategory</SelectLabel>
{filteredSubcategories.map((option, index) => (
<SelectItem key={index} value={option}>
{option}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</FormItem>
)}
/>
</div>
<Button type="submit" className="w-full">
Save
</Button>
</form>
</Form>
</CardWrapper>
);
};
您遇到此问题是因为您没有设置要形成的选定类别值,在您的情况下,您可以这样做:
const handleCategoryChange = (category: string) => {
setSelectedCategory(category);
setSelectedSubcategory("");
console.log(category);
form.setValue("category",category) // setting category value to form
const categoryData = dummyData.categories.find(
(item) => item.name === category
);
if (categoryData) {
setFilteredSubcategories(categoryData.subcategories);
} else {
setFilteredSubcategories([]);
}
};
注意:您可以避免额外的
useState
钩子,如果您想要任何表单项的反应值,您可以使用 form.watch()