React中使用useEffect设置Formik初始值时Memo字段无法加载数据
React useEffect设置Formik表单初始值时Memo字段无法加载数据的问题
我尝试在React的useEffect钩子中设置表单的初始值,但Memo字段无法加载任何数据,请问我的代码存在什么问题?
原代码:
状态与请求逻辑:
const [initialValues, setInitialValues] = useState<PurchaseOrderDto>(); useEffect(() => { agent.PurchaseOrder.List(id).then((response) => { setInitialValues(response.data); }); }, []);
Formik表单组件:
return ( <Formik enableReinitialize initialValues={ initialValues } onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => { try { } catch (error: any) { const message = error.message || "Something went wrong"; setStatus({ success: false }); setErrors({ submit: message }); setSubmitting(false); } }} > {({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => ( <form noValidate onSubmit={handleSubmit}> {errors.submit && ( <Alert mt={2} mb={1} severity="warning"> {errors.submit} </Alert> )} <TextField type="text" name="Memo" label="Memo" value={initialValues?.memo} //error={Boolean(touched.Memo && errors.Memo)} fullWidth helperText={values?.memo && errors.memo} onBlur={handleBlur} onChange={handleChange} my={3} /> )} </Formik>
问题分析与解决方案
你的代码存在三个核心问题,导致Memo字段无法加载数据:
字段值绑定错误:你直接将TextField的
value绑定到外部状态initialValues?.memo,但Formik通过自身的values对象管理表单状态。即使initialValues更新,直接绑定外部状态会绕过Formik的状态同步机制,导致字段无法正确加载初始值,还会引发后续的状态不一致问题。字段名大小写不匹配:
initialValues中的字段是memo(小写),但TextField的name属性是Memo(首字母大写)。Formik依赖name属性映射values中的对应字段,大小写不匹配会导致Formik无法找到对应的值,自然无法渲染初始数据。初始状态未初始化:
initialValues的初始值是undefined,虽然Formik的enableReinitialize会在值更新时重新初始化,但未初始化的状态可能导致Formik在首次渲染时无法正确处理字段,引发渲染异常。
修正后的代码
状态与请求逻辑修正:
// 初始化空对象,避免undefined导致的渲染问题 const [initialValues, setInitialValues] = useState<PurchaseOrderDto>({}); useEffect(() => { agent.PurchaseOrder.List(id).then((response) => { setInitialValues(response.data); }); }, [id]); // 添加id作为依赖项,确保id变化时重新请求数据
Formik表单组件修正:
return ( <Formik enableReinitialize initialValues={ initialValues } onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => { try { // 在这里添加你的提交逻辑 } catch (error: any) { const message = error.message || "Something went wrong"; setStatus({ success: false }); setErrors({ submit: message }); setSubmitting(false); } }} > {({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values }) => ( <form noValidate onSubmit={handleSubmit}> {errors.submit && ( <Alert mt={2} mb={1} severity="warning"> {errors.submit} </Alert> )} <TextField type="text" name="memo" // 与initialValues中的字段名保持一致(小写) label="Memo" value={values.memo || ''} // 绑定Formik提供的values,空值时赋默认空字符串 error={Boolean(touched.memo && errors.memo)} // 修正字段名大小写 fullWidth helperText={touched.memo && errors.memo} // 仅在触摸字段后显示错误提示 onBlur={handleBlur} onChange={handleChange} my={3} /> </form> )} </Formik> )
内容的提问来源于stack exchange,提问作者Joseph Anderson
相关产品推荐
相关产品推荐

