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

Formik提交表单时如何移除最终JSON中的隐藏字段值

Formik条件渲染字段隐藏后仍提交旧值问题

问题现象

基于Formik搭建React表单时,单选按钮选择no选项会通过条件渲染隐藏input2字段。若先在input2中输入内容,再选择no隐藏字段后提交表单,最终生成的提交JSON中仍然保留该隐藏字段的已输入值,预期效果为 字段不在页面渲染时,自动从最终提交结果中移除。

问题复现代码

import React from "react";
import { Formik } from "formik";
import { Form } from "react-bootstrap";
import { Radio } from "antd";

const CustomFormik = () => {
  return (
    <>
      <Formik
        initialValues={{
          input1: null,
          radio: null,
          input2: null
        }}
        onSubmit={(values) => {
          console.log(values);
        }}
      >
        {(formik) => (
          <>
            <Form
              onSubmit={formik.handleSubmit}
              className="custom-formik-container"
            >
              <Form.Group>
                <span>input1: </span>
                <Form.Control
                  id={"input1"}
                  name={"input1"}
                  {...formik.getFieldProps("input1")}
                />
              </Form.Group>

              {formik.getFieldProps("radio").value !== 2 && (
                <Form.Group>
                  <span>input2: </span>
                  <Form.Control
                    id={"input2"}
                    name={"input2"}
                    {...formik.getFieldProps("input2")}
                  />
                </Form.Group>
              )}

              <Form.Group>
                <span>radio: </span>
                <Radio.Group {...formik.getFieldProps("radio")}>
                  <Radio value={1}>yes</Radio>
                  <Radio value={2}>no</Radio>
                </Radio.Group>
              </Form.Group>
            </Form>

            <button
              style={{
                width: 200,
                height: 30,
                background: "#113776",
                color: "#fff"
              }}
              onClick={() => formik.handleSubmit()}
            >
              S U B M I T
            </button>
          </>
        )}
      </Formik>
    </>
  );
};
export default CustomFormik;

复现步骤

  • 在input1输入框中输入abc
  • 在input2输入框中输入efg
  • 单选按钮选择no选项后提交

实际输出结果

{input1: "abc",input2: "efg", radio: 2}

预期输出结果

{input1: "abc", radio: 2}

原因说明

Formik默认不会因为DOM字段被条件卸载,就自动清除内部状态存储的对应字段值,所以即使输入框已经隐藏,之前输入的内容仍然保存在Formik的values状态中,提交时会被一并带出。

解决方案

根据业务场景二选一即可:

方案1:隐藏字段时同步清空状态值

适合切回显示字段时不需要保留用户之前输入内容的场景。

  1. 首先引入React的useEffect钩子
import React, { useEffect } from "react";
  1. 在Formik的渲染函数内部添加监听逻辑,当单选值变为no时,清空input2的存储值:
{(formik) => {
  // 新增监听逻辑
  useEffect(() => {
    if (formik.values.radio === 2) {
      formik.setFieldValue("input2", undefined);
    }
  }, [formik.values.radio]);

  return (
    // 原有JSX内容保持不变
    <>...</>
  )
}}
  1. 最后修改onSubmit逻辑,过滤掉值为undefined的字段即可:
onSubmit={(values) => {
  // 剔除值为undefined的字段
  const submitData = Object.fromEntries(
    Object.entries(values).filter(([_, val]) => val !== undefined)
  );
  console.log(submitData);
}}

方案2:提交时按条件过滤字段

适合用户切回显示字段时需要保留之前输入内容的场景,不需要修改表单交互逻辑,仅在提交层处理数据:
直接修改Formik的onSubmit配置即可:

onSubmit={(values) => {
  const submitData = { ...values };
  // 选中no选项时移除input2字段
  if (values.radio === 2) {
    delete submitData.input2;
  }
  console.log(submitData);
  // 后续接口提交使用submitData即可
}}

内容的提问来源于stack exchange,提问作者dor.co

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:06:22