antd Form多表单问题解决
antd的多表单冲突问题
最近写了一个项目,是通过函数条件化渲染特定内容,其中每一种特定内容都包含一个表单
源码部分如下(源码太长,只截取必要部分)
// 题目类型展示
const ShowQuestionType = () => {
switch (type) {
case 1: case 2:
return (
<div>
{/* 第1个Form表单 */}
<Form form={form} onValuesChange={handleFormChange}>
<div className={Style.configSearch}>
<div className={Style.selectDiv}>
<Form.Item name="departmentList">
{/* 表单内容1 */}
</Form.Item>
</div>
<div className={Style.selectDiv}>
<div className={Style.selectTitle}>参与角色: </div>
<Form.Item name="roleList">
{/* 表单内容2 */}
</Form.Item>
</div>
</div>
</Form>
</div>
);
case 3:
return (
<div>
<div className={Style.chartMain3}>
{/* 第2个Form表单 */}
<Form form={form} onValuesChange={handleFormChange}>
<div className={Style.configSearch}>
<div className={Style.selectDiv}>
<Form.Item name="departmentList">
{/* 表单内容5 */}
</Form.Item>
</div>
<div className={Style.selectDiv}>
<div className={Style.selectTitle}>参与角色: </div>
<Form.Item name="roleList">
{/* 表单内容6 */}
</Form.Item>
</div>
</div>
</Form>
</div>
</div>
);
default:
return <></>;
}
};
这里是通过switch,条件渲染指定的表单,其中第一次写每一个大的Form都用的
<Form form={form} onValuesChange={handleFormChange}>
但是之后我们发现,两个表单中有一些组件是一样的,Form.Item的name也是一样的,这样的话会导致不同的Form中的相同name的Form.Item会互相冲突
那么之后我将所有的Form.Item的name都进行了区分,使他们每一个都唯一的,这样有个缺点是,在handleFormChange函数中得重新定义不同的name,非常麻烦,但还是先改吧
本以为完事大吉,但是发现执行下面这个函数的时候
form.resetFields()
会导致两个表单都刷新重置
这是肯定的,因为我两个Form都是定义的
const [form] = Form.useForm();
<Form form={form} onValuesChange={handleFormChange}>
// 第一个表单的内容
<Form form={form} onValuesChange={handleFormChange}>
// 第二个表单的内容
都用的form={form},那么我执行form.resetFields(),两个表单都会重置也就情理之中了
那么我就将两个Form的命名区分
const [form] = Form.useForm();
const [forms] = Form.useForm();
<Form form={form} onValuesChange={handleFormChange}>
// 第一个表单的内容
<Form form={forms} onValuesChange={handleFormChange}>
// 第二个表单的内容
那么我就想,反正每个Form都单独命名了,那我每个Form.Item的name不需要分的那么细,handleFormChange函数中也不需要区分那么多不同的name了,于是我又将每个Form.item改了回来
// 题目类型展示
const ShowQuestionType = () => {
switch (type) {
case 1: case 2:
return (
<div>
{/* 第1个Form表单 */}
<Form form={form} onValuesChange={handleFormChange}>
<div className={Style.configSearch}>
<div className={Style.selectDiv}>
<Form.Item name="departmentList">
{/* 表单内容1 */}
</Form.Item>
</div>
<div className={Style.selectDiv}>
<div className={Style.selectTitle}>参与角色: </div>
<Form.Item name="roleList">
{/* 表单内容2 */}
</Form.Item>
</div>
</div>
</Form>
</div>
);
case 3:
return (
<div>
<div className={Style.chartMain3}>
{/* 第2个Form表单 */}
<Form form={forms} onValuesChange={handleFormChange}>
<div className={Style.configSearch}>
<div className={Style.selectDiv}>
<Form.Item name="departmentList">
{/* 表单内容5 */}
</Form.Item>
</div>
<div className={Style.selectDiv}>
<div className={Style.selectTitle}>参与角色: </div>
<Form.Item name="roleList">
{/* 表单内容6 */}
</Form.Item>
</div>
</div>
</Form>
</div>
</div>
);
default:
return <></>;
}
};
之后我发现一个很神奇的事情,就算是给每个Form单独命名了form={form},但是如果Form.Item一样,还是会冲突
(表单Item的name一样,但是Form的引用不一样)
查了一下,这是因为antd表单无论有多少个Form,实际上只会创建一个form实例,在这个实例中会绑定name,所以如果多表单的Form.Item,需要严格把不同的name给区分开,防止冲突
但是对于每一个form的api,因为我们采用的是form.resetFields()和forms.resetFields(),是antd通过form这个api绑定的,不会冲突
更多推荐
所有评论(0)