You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Formik表单初始值同步问题:Props变更与提交更新冲突

问题原因
  1. useEffect依赖项不合理:你监听了整个props对象作为依赖,React中对象的引用会随父组件渲染频繁变化(即使内容没实质更新),导致useEffect频繁触发,直接把initialValues重置回props的初始状态,覆盖了你提交时通过setInitialValues追加的评论内容。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 21:57:47