React Formik initialValues获取props值为undefined问题
Formik initialValues 异步props赋值失效问题修复
问题现象
- 父组件传入的
ApplicantImgID属性,在Step3组件顶层执行console.log可以正常打印最新值 - Formik的initialValues中给
ApplicantImage字段赋值后,表单提交时拿到的始终是父组件中该状态的初始值,拿不到更新后的值 - 同属props传入的
aadharId可以在initialValues中正常赋值,无异常
根本原因
Formik的initialValues默认仅在组件首次挂载时读取一次,后续组件接收到的props更新,不会自动同步到已经初始化完成的表单状态中。
你这里的aadharId是Step3组件挂载前就已经拿到确定值的,所以初始化时能正常赋值;但ApplicantImgID是Step3挂载完成后才异步更新拿到的值(比如用户上传完图片才触发父组件setState更新),此时Formik已经完成初始化,自然不会自动更新字段值,提交时拿到的就是初始化时的初始值。
解决方案
方案1:开启Formik自动重初始化(适合表单无用户已填内容的场景)
给Formik组件添加enableReinitialize={true}属性,配置后只要initialValues的引用发生变化,Formik会自动重置整个表单状态为新的initialValues值。
修改后的Formik代码片段:
<Formik enableReinitialize={true} initialValues={{ Name: "", PhoneNumber: "", Address: "", AadharNumber: "", AadharPdf:`${aadharId}`, ApplicantImage:`${ApplicantImgID}`, }} onSubmit={(values) => { handleSubmit(values); }} > {/* 其余表单逻辑保持不变 */} </Formik>
注意:该方案触发重初始化时会清空用户已经填写的所有表单内容,如果你的流程是用户先填其他字段、最后上传图片拿到ApplicantImgID,不要用这个方案。
方案2:手动同步字段值(推荐,不影响用户已填内容)
不需要依赖initialValues同步异步值,两种实现方式选其一即可:
- 提交时直接覆盖值:不需要改表单初始化逻辑,在提交方法里直接拿最新的props值覆盖对应字段
const handleSubmit = async (values) => { // 直接用组件拿到的最新ApplicantImgID组装提交数据 const submitParams = { ...values, ApplicantImage: ApplicantImgID } try { applyGharwapasihandle({ variables: { data: submitParams, }, }); } catch (error) { console.log(error); } };
- 监听props变化手动更新表单字段:如果需要表单输入框同步显示拿到的
ApplicantImgID,可以通过useEffect监听值变化,调用Formik提供的setFieldValue手动更新字段
<Formik initialValues={{ Name: "", PhoneNumber: "", Address: "", AadharNumber: "", AadharPdf:`${aadharId}`, ApplicantImage:"", }} onSubmit={(values) => { handleSubmit(values); }} > {({ setFieldValue }) => { // 监听ApplicantImgID变化,更新对应表单字段 React.useEffect(() => { if (ApplicantImgID) { setFieldValue('ApplicantImage', ApplicantImgID) } }, [ApplicantImgID, setFieldValue]) return ( <Form> {formArray.map((item, index) => ( <InputField key={index} label={item.label} placeholder={item.placeholder} type={item.type} name={item.name}/> ))} <button type="submit" className="btn btn-primary col-md-12 my-3"> Submit </button> </Form> ) }} </Formik>
内容的提问来源于stack exchange,提问作者sarangkkl
相关产品推荐
相关产品推荐

