React Hook Form useFieldArray动态字段提交无数据问题求助
问题:React Hook Form useFieldArray动态字段提交无数据返回
使用React Hook Form结合Material UI构建表单,通过useFieldArray Hook实现票种字段的动态添加与删除,增删功能正常,但提交表单时,动态字段对应的ticketCategory数组无数据返回,非动态字段(如eventName、eventVenue等)数据正常。
相关代码
表单主组件代码
<Box component="form" onSubmit={handleSubmit(submit)}> <Grid container spacing={2}> <Grid item xs={12} sm={12} md={12} lg={12}> <TextField label="Evnet Name" fullWidth {...register("eventName")} name="eventName" /> </Grid> <Grid item xs={12} sm={12} md={6} lg={6} alignSelf="center"> <TextField label="Evnet Venue Name" fullWidth {...register("eventVenue")} name="eventVenue" /> </Grid> <Box sx={{ width: "100%" }}> <DialogTitle sx={{ fontWeight: "bold", textTransform: "uppercase" }} > Ticket Category </DialogTitle> </Box> <Grid item xs={12} sm={12} md={5} lg={4}> <TextField label="Category" fullWidth {...register("ticketCatName")} name="ticketCatName" /> </Grid> <Grid item xs={12} sm={12} md={3} lg={3}> <TextField type="number" label="Price" fullWidth {...register("ticketCatPrice")} name="ticketCatPrice" /> </Grid> <Grid item xs={12} sm={12} md={3} lg={3}> <TextField type="number" label="Total" fullWidth {...register("ticketCatTotal")} name="ticketCatTotal" /> </Grid> This Values I am getting when I submit the form. </Box>
动态字段渲染代码
{fields.map((item, index) => { return ( <MoreFields register={register} key={item.id} remove={remove} index={index} item={item} control={control} /> ); })}
MoreFields组件代码
import { Box, Grid, IconButton, SvgIcon, TextField } from "@mui/material"; import React from "react"; import DeleteIcon from '@mui/icons-material/Delete'; import { Fragment } from "react"; const MoreFields = ({ register, remove, index, item }) => { return ( <Fragment key={item.id}> <Grid item xs={12} sm={12} md={5} lg={4}> <TextField label="Category" fullWidth {...register(`ticketCategory.${index}.ticketCatName`)} name={`ticketCategory${index}.ticketCatName`} defaultValue={item.ticketCatName} /> </Grid> <Grid item xs={12} sm={12} md={3} lg={3}> <TextField type="number" label="Price" fullWidth {...register(`ticketCategory.${index}.ticketCatPrice`)} name={`ticketCategory${index}.ticketCatPrice`} defaultValue={item.ticketCatPrice} /> </Grid> <Grid item xs={12} sm={12} md={3} lg={3}> <TextField type="number" label="Total" fullWidth {...register(`ticketCategory.${index}.ticketCatTotal`)} name={`ticketCategory${index}.ticketCatTotal`} defaultValue={item.ticketCatTotal} /> </Grid> <Grid item xs={4} sm={4} md={2} lg={2} alignSelf="center"> <SvgIcon color='error' onClick={()=>remove(index)} sx={{cursor:'pointer'}}> <DeleteIcon size="medium" /> </SvgIcon> </Grid> </Fragment> ); }; export default MoreFields;
Hook及相关函数代码
const { register, handleSubmit, control } = useForm(); const { fields, append, prepend, remove, swap, move, insert } = useFieldArray( { control, name: "ticketCategory", } ); const addFields = () => { append({ ticketCatName: "", ticketCatPrice: "", ticketCatTotal: "" }); }; const submit = (data) => { console.log(data); };
问题原因及修复方案
1. MoreFields组件name属性路径冲突
{...register(ticketCategory.${index}.ticketCatName)}已经自动生成了正确的name属性,但你手动设置的name={ticketCategory${index}.ticketCatName}覆盖了它,路径缺少了层级分隔的点号,导致React Hook Form无法将字段关联到ticketCategory数组。
修复:删除所有手动设置的name属性,直接使用register注入的属性即可。修改后的字段示例:
<TextField label="Category" fullWidth {...register(`ticketCategory.${index}.ticketCatName`)} defaultValue={item.ticketCatName} />
2. 初始票种字段未纳入数组管理
主组件中直接渲染的ticketCatName、ticketCatPrice、ticketCatTotal是独立字段,不属于ticketCategory数组,这部分数据不会被收集到目标数组中,还会和动态字段逻辑冲突。
修复:
- 移除主组件中这三个独立的票种字段
- 初始化
useForm时设置默认值,让ticketCategory默认包含一个空对象作为初始字段:
const { register, handleSubmit, control } = useForm({ defaultValues: { eventName: "", eventVenue: "", ticketCategory: [{ ticketCatName: "", ticketCatPrice: "", ticketCatTotal: "" }] } });
3. 保持字段路径一致性
确保所有动态字段的register路径都以ticketCategory.${index}.xxx格式书写,与useFieldArray的name参数完全匹配。
内容的提问来源于stack exchange,提问作者nehat khan
相关产品推荐
相关产品推荐

