如何在Select组件中渲染关联表的姓名并设置为默认值
如何在Select组件中渲染关联表的姓名并设置为默认值
看起来你遇到的核心问题是Select组件的值与显示文本不匹配,导致默认值无法正确渲染。咱们一步步来解决这个问题:
1. 修正表单默认值的设置逻辑
你现在在form.reset里把authorId设为了data.Authors.first_name,但你的Select选项的value是作者的id,这就导致表单值和选项值不匹配,自然无法显示对应的姓名。
把useEffect里的重置代码改成这样:
useEffect(() => { if (data) { form.reset({ title: data.title || "", authorId: data.Authors.id, // 这里要设置为作者的ID,而非姓名 }); } }, [data, form]);
同时,FormField里的defaultValue可以删掉,因为表单已经通过reset方法设置了默认值,不需要重复定义。
2. 调整Select组件的绑定逻辑
你的Select组件需要正确绑定表单字段的value和onChange,确保它是受控组件。修改这部分代码:
<FormField control={form.control} name="authorId" render={({ field }) => ( <FormItem className="w-full"> <Select value={field.value} // 用field.value绑定当前表单值,而非defaultValue onValueChange={field.onChange} > <FormControl> <SelectTrigger className="w-full"> <SelectValue placeholder="Author" /> </SelectTrigger> </FormControl> <SelectContent className='w-full'> {listofAuthors.data.map((author: ListOfAuthors) => ( <SelectItem key={author.id} value={author.id}> {author.first_name} {author.last_name || author.middle_name} </SelectItem> ))} </SelectContent> </Select> <FormMessage /> </FormItem> )} />
这里注意两点:
- 去掉了多余的
React.Fragment,SelectItem可以直接作为SelectContent的子元素 - 加了
|| author.middle_name的判断,因为你提供的API返回数据里没有last_name,避免显示空白
3. 处理加载状态,避免报错
因为数据是异步获取的,在isLoading状态下直接访问data.Authors会导致报错,建议在组件开头添加加载判断:
if (isLoading) { return <div>加载中...</div>; }
4. 验证API返回数据的完整性
你提供的示例数据里,Authors对象没有last_name字段,但你的Select里要显示first_name + last_name,如果这是API的遗漏,记得在后端查询里确保返回last_name:
// 后端API调整(如果需要返回last_name) const authors = await db.publish_Papers.findFirst({ where: { id: params.id }, include: { Authors: { select: { id: true, first_name: true, last_name: true, // 确保返回这个字段 middle_name: true, } }, } })
这样调整后,Select组件就能根据表单里的authorId(作者ID)自动匹配对应的选项,显示出first_name + last_name的组合作为默认值了。
备注:内容来源于stack exchange,提问作者Stykgwar
相关产品推荐
相关产品推荐

