如何基于React State从API加载表单字段并实现带校验提交?
动态表单字段的值获取与提交修改
需求场景
我有一个API,返回包含text、单选框、日期选择器、下拉框等多种输入类型的属性数据,需要根据属性的attribute_code渲染对应输入组件,输入类型由属性的frontend_input字段决定。核心要实现:获取所有字段的值,并在表单提交时修改这些值。
现有代码存在的问题
- Text类型组件的
return语句后直接换行,导致JSX未被正确返回(语法错误) - Select组件未关联React Hook Form的表单状态,硬编码初始值且自定义
handleChange未同步表单数据 - DatePicker未通过
Controller集成到React Hook Form,无法将选中日期同步到表单状态 - 仅监听了特定字段(如
name),无法处理动态生成的所有字段值
修正后的完整组件代码
{attributes?.map(subOption => { switch (subOption?.frontend_input) { case 'text': return ( <Controller name={subOption.attribute_code} control={control} render={({ field, fieldState: { error } }) => ( <TextField {...field} className="mt-8 mb-16" error={!!error} required label={subOption.default_frontend_label} helperText={error?.message} id={subOption.attribute_code} variant="outlined" fullWidth /> )} /> ); case 'select': return ( <Controller name={subOption.attribute_code} control={control} render={({ field, fieldState: { error } }) => ( <Select {...field} className="mt-8 mb-16" labelId={`${subOption.attribute_code}-label`} id={subOption.attribute_code} label={subOption.default_frontend_label} style={{ margin: "10px 0px" }} fullWidth error={!!error} > <MenuItem key="" value="" > {`请选择${subOption.default_frontend_label}`} </MenuItem> {subOption?.options?.map(selectOption => ( <MenuItem key={selectOption?.value} value={selectOption?.value}> {selectOption?.label} </MenuItem> ))} </Select> )} /> ); case 'date': return ( <LocalizationProvider dateAdapter={AdapterDayjs}> <Controller name={subOption.attribute_code} control={control} render={({ field, fieldState: { error } }) => ( <DatePicker {...field} className="mt-8 mb-16" label={subOption.default_frontend_label} renderInput={(params) => ( <TextField {...params} error={!!error} helperText={error?.message} fullWidth /> )} /> )} /> </LocalizationProvider> ); default: return <div>不支持的输入类型</div>; } })}
提交时获取并修改所有字段值
const { formState, watch, getValues } = methods; // 可选:监听所有字段实时变化 const allFieldValues = watch(); function handleSaveProduct() { // 1. 获取当前所有表单字段的值 let formValues = getValues(); // 2. 按需修改字段值,示例: // 去除文本字段首尾空格 if (formValues.name) { formValues.name = formValues.name.trim(); } // 格式化日期字段 if (formValues.date_field) { formValues.date_field = formValues.date_field.format('YYYY-MM-DD'); } // 转换下拉框值为数字类型 if (formValues.select_field) { formValues.select_field = parseInt(formValues.select_field, 10); } // 3. 提交修改后的数据 console.log("修改后的表单值", formValues); dispatch(saveProduct(formValues)); }
关键说明
- 所有动态字段通过
Controller与React Hook Form绑定,确保值同步到表单状态 getValues()可一次性获取所有字段当前值,无需单独监听每个字段- 提交时直接修改
getValues()返回的对象,再传入dispatch即可完成值的修改
内容的提问来源于stack exchange,提问作者Manik
相关产品推荐
相关产品推荐

