Formik表单两大问题:下拉选框数据不渲染+教会字段状态未读取
问题解决方案
1. 群组下拉选框数据不渲染问题
原因
在useEffect中获取群组数据后,你将其映射为包含label和value属性的对象数组,但渲染MenuItem时错误使用了原数据的groupId和groupName属性,导致无法读取正确字段值,下拉选项因此无法显示。
修复代码
修改Form中群组下拉框的map逻辑:
<TextField fullWidth variant="filled" sx={{ gridColumn: "span 2" }} select id="group" label="Group" onBlur={handleBlur} onChange={handleChange} value={values.group ?? ""} name="group" error={!!touched.group && !!errors.group} helperText={touched.group && errors.group} > {groups.map((group) => ( <MenuItem key={group.value} value={group.value}> {group.label} </MenuItem> ))} {console.log("Current value of 'group':", values.group)} </TextField>
若需要保留原ID,可在useEffect的映射逻辑中补充:
const groups = groupResponse.$values.map(group => ({ label: group.groupName, value: group.groupId.toString(), groupId: group.groupId // 可选,保留原ID方便后续使用 }));
2. 教会字段状态未被Formik读取问题
原因
- Formik默认不收集disabled字段的值,即便设置了
value也不会同步到Formik的values中; - 当前字段
value直接绑定getChurchNameById(churchId),未关联Formik的values.church,也未触发Formik状态更新; getChurchNameById函数存在逻辑错误:find条件误用状态变量churchId而非传入的参数id。
修复方案
第一步:修复getChurchNameById函数
const getChurchNameById = (id) => { if (id === null || id === undefined) { return ""; } // 修复:使用传入的id参数而非状态变量churchId const church = churches.find((church) => church.churchId === parseInt(id)); return church ? church.churchName : ""; };
第二步:同步教会字段到Formik状态
选择以下任一方案:
方案一:用readonly替代disabled(推荐)
若仅需禁止用户编辑而非完全禁用,将disabled改为readonly,Formik会自动收集字段值:
// 在Formik的render props中解构出setFieldValue {({values,errors, touched, handleBlur, handleChange, handleSubmit, setFieldValue})=>( // ...其他表单组件 <TextField fullWidth variant="filled" type="text" label="Church" onBlur={handleBlur} onChange={handleChange} value={values.church} name="church" readonly // 替换disabled为readonly sx={{ gridColumn: "span 4" }} /> )}
添加useEffect监听数据变化,更新Formik状态:
useEffect(() => { const churchName = getChurchNameById(churchId); setFieldValue('church', churchName); }, [churchId, churches, setFieldValue]);
同时初始化initialValues时设置初始值:
const initialValues = { firstName: "", lastName: "", gender: "", group: "", church: getChurchNameById(churchId) || "", isActive: "" }
方案二:保留disabled并手动同步状态
若必须使用disabled,通过setFieldValue手动同步状态:
<TextField fullWidth variant="filled" type="text" label="Church" value={values.church} name="church" disabled sx={{ gridColumn: "span 4" }} />
同样添加useEffect同步状态(需解构setFieldValue):
useEffect(() => { const churchName = getChurchNameById(churchId); setFieldValue('church', churchName); }, [churchId, churches, setFieldValue]);
内容的提问来源于stack exchange,提问作者Timmy
相关产品推荐
相关产品推荐

