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:隐藏字段时同步清空状态值
适合切回显示字段时不需要保留用户之前输入内容的场景。
- 首先引入React的
useEffect钩子
import React, { useEffect } from "react";
- 在Formik的渲染函数内部添加监听逻辑,当单选值变为
no时,清空input2的存储值:
{(formik) => { // 新增监听逻辑 useEffect(() => { if (formik.values.radio === 2) { formik.setFieldValue("input2", undefined); } }, [formik.values.radio]); return ( // 原有JSX内容保持不变 <>...</> ) }}
- 最后修改
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
相关产品推荐
相关产品推荐

