整合TanStack Table时react-hook-form FieldArray无法输入值
问题分析与修复方案
问题根源
当前输入框无法更新值的核心原因是:输入框的value绑定依赖TanStack Table行的静态映射数据,而非React Hook Form的实时状态;同时手动映射data的过程可能导致表格未及时响应表单状态变化,最终出现输入内容无法同步的情况。
修复方案1:直接绑定表单响应式数据(推荐)
利用React Hook Form的useController实现输入框与表单状态的双向绑定,同时直接使用useFieldArray返回的fields作为表格数据源,避免额外映射导致的状态不同步。
步骤1:修改主表单代码
移除手动映射的data,直接将systemUsers传给表格:
const { fields: systemUsers, append: appendSystemUser } = useFieldArray({ control: form.control, name: "systemUsers", }); const columns = getColumns({ isEditing, onRemove: removeSystemUser, control: form.control, // 新增传入form的control }); // 直接使用systemUsers作为表格数据源 return ( <DataTable columns={columns} data={systemUsers} /> );
步骤2:修改列定义代码
通过useController绑定输入框与表单字段:
import { useController } from "react-hook-form"; export const getColumns = ({ isEditing, control, }: SystemUsersTableProps): ColumnDef<CompanySystemUserType>[] => [ { accessorKey: "name", header: "Employee Name", cell: ({ row }) => { const index = row.index; // 使用useController绑定对应字段 const { field } = useController({ control, name: `systemUsers.${index}.name`, defaultValue: "", }); return isEditing ? ( <Input value={field.value} onChange={field.onChange} onBlur={field.onBlur} /> ) : ( <span>{field.value || ""}</span> ); }, }, // Role列同理修改 { accessorKey: "role", header: "Role", cell: ({ row }) => { const index = row.index; const { field } = useController({ control, name: `systemUsers.${index}.role`, defaultValue: "", }); return isEditing ? ( <Input value={field.value} onChange={field.onChange} onBlur={field.onBlur} /> ) : ( <span>{field.value || ""}</span> ); }, }, ];
修复方案2:保留现有结构,绑定实时表单状态
如果不想调整数据源结构,可通过watch方法获取表单实时状态,替换原有的row.getValue:
import { useFormContext } from "react-hook-form"; export const getColumns = ({ isEditing, }: SystemUsersTableProps): ColumnDef<CompanySystemUserType>[] => [ { accessorKey: "name", header: "Employee Name", cell: ({ row }) => { const index = row.index; const { watch, setValue } = useFormContext(); // 实时获取表单字段值 const currentValue = watch(`systemUsers.${index}.name`) || ""; return isEditing ? ( <Input value={currentValue} onChange={(e) => setValue(`systemUsers.${index}.name`, e.target.value)} /> ) : ( <span>{currentValue}</span> ); }, }, // Role列同理修改 ];
关键注意事项
- 必须在
useForm的defaultValues中初始化systemUsers字段:const form = useForm({ defaultValues: { systemUsers: [], }, }); - 避免手动复制或映射表单状态数据,优先使用React Hook Form提供的响应式数据(如
fields、watch结果),确保状态同步。
内容的提问来源于stack exchange,提问作者J_Max
相关产品推荐
相关产品推荐

