Formik表单初始值同步问题:Props变更与提交更新冲突
问题原因
- useEffect依赖项不合理:你监听了整个
props对象作为依赖,React中对象的引用会随父组件渲染频繁变化(即使内容没实质更新),导致useEffect频繁触发,直接把initialValues重置回props的初始状态,覆盖了你提交时通过setInitialValues追加的评论内容。 - resetForm与useEffect执行顺序冲突:提交后调用
formik.resetForm()会基于当前initialValues重置表单,但如果此时useEffect刚好触发,会把initialValues打回原形,导致新评论无法保留。
可行解决方案
方案一:精准监听props依赖,避免不必要的重置
把useEffect的依赖从整个props改成具体的、会影响表单的字段,只有当这些核心数据真正变化时,才同步更新initialValues:
useEffect(() => { setInitialValues({ forename: props?.membersCommentsData?.[0].forename ?? '', surname: props?.membersCommentsData?.[0].surname ?? '', address_1: props?.membersCommentsData?.[0].address_1 ?? '', last_updated_by: userNameConcatenated, member_id: props?.membersCommentsData?.[0].member_id ?? '', existing_member_comments: joinedArray, }); }, [props.membersCommentsData, userNameConcatenated]); // 只监听具体依赖项
方案二:拆分state,分离props同步与本地追加逻辑
把existing_member_comments单独抽成一个state,其他字段直接从props读取(无需存入state),既保证其他字段随props自动同步,又能独立控制评论的追加:
function MembersCommentsEdit(props) { const { mutate } = useMembersCommentsCreateMutation(); // 单独管理评论列表的state,初始值来自props const [existingComments, setExistingComments] = useState(joinedArray); // 当切换成员时,重置评论列表 useEffect(() => { setExistingComments(joinedArray); }, [props.membersCommentsData]); // Formik的initialValues直接合并props字段和本地state const formInitialValues = { forename: props?.membersCommentsData?.[0].forename ?? '', surname: props?.membersCommentsData?.[0].surname ?? '', address_1: props?.membersCommentsData?.[0].address_1 ?? '', last_updated_by: userNameConcatenated, member_id: props?.membersCommentsData?.[0].member_id ?? '', existing_member_comments: existingComments, }; return ( <Formik enableReinitialize={true} initialValues={formInitialValues} validationSchema={validationSchema} onSubmit={(values, formik) => { mutate(values, { onSuccess: () => { setOpen(true); setMessage('Member comment saved!'); setSeverity('success'); setButtonIsClicked(prev => prev + 1); // 只更新评论列表的state setExistingComments(prev => `Created On: ${today}\nAdded by: ${values.last_updated_by}\nComment: ${values.member_comment}\n \n${prev}` ); formik.resetForm(); } }); }} > {/* 表单内容 */} </Formik> ); }
方案三:判断成员是否切换再重置
如果只有当切换不同成员(member_id变化)时才需要重置表单,其他props变化不影响已追加的评论,可以在useEffect中增加判断逻辑:
useEffect(() => { const newMemberId = props?.membersCommentsData?.[0].member_id ?? ''; const currentMemberId = initialValues.member_id; // 只有当成员ID变化时,才重置initialValues if (newMemberId !== currentMemberId) { setInitialValues({ forename: props?.membersCommentsData?.[0].forename ?? '', surname: props?.membersCommentsData?.[0].surname ?? '', address_1: props?.membersCommentsData?.[0].address_1 ?? '', last_updated_by: userNameConcatenated, member_id: newMemberId, existing_member_comments: joinedArray, }); } }, [props.membersCommentsData, userNameConcatenated]);
内容的提问来源于stack exchange,提问作者Jess
相关产品推荐
相关产品推荐

