2

* 前言

在写项目遇到动态新增一整个form表单的需求,当时还遇到坑了,没有get到正确的姿势,所以解决问题就想着写这个文章记录一下。
简易版在线demo:https://stackblitz.com/edit/react-x435fn?embed=1&file=index.js

* 需求

因为form里面的数据还需要正则校验之类的,为了方便,所以打算使用antd的form来写。
form通过数据遍历出来,每个form都可以删除,也可以新增form。
最终实现效果如图:
image.png

* 问题与解决

1. 如何保存数据?

当删除一个form时,form中删除的数据出错。而且,每个form的数据还需要函数二次处理。

解决:当时getFieldDecorator的写法不是很正确,应该按照下图这么写 getFieldDecorator(content[${index}].source)
这样就把每个form的数据保存在对应的content[index]中,并且form里每项的数据格式也对应了(content[index].xx)。

arr.map((item,index)=>(
    <div className={styles.content} key={index}>
    <Icon type="close" className={styles.close} onClick={deleteContent.bind(this,index)}/>
    <Form {...formItemLayout}>
        <Form.Item style={{ width: '50%' }} label="xxx">
            {getFieldDecorator(`content[${index}].source`, {
            initialValue: item.source,
            rules: [],
            })(<Input placeholder="xxx" />)}
        </Form.Item>
...

1. 如何删除form?

这样解决了正确在遍历出来的form里存储数据的问题,现在要之前删除form之后,数据出错的问题。其实有了上面的修改,这步就简单多了。
1、使用form提供的api getFieldValue 获取到整个content数据
2、setFieldsValue,可以设置form的值。使用filter把要删除的数据过滤掉
3、把arr里的要删除的form也删掉,因为form是通过arr遍历出来的。arr.splice(index,1)

const deleteContent = (index)=>{
        confirm({
            title: '确定要删除吗?',
            onOk() {
                const content = form.getFieldValue('content');
                form.setFieldsValue({
                  content: content.filter((item, key) => key !== index),
                });
                arr.splice(index,1)
                dispatch({
                    type: 'xxx/updateStates',
                    payload: {
                        arr
                    }
                })
            },
            onCancel() {},
          });
    }

* 结语

好了,写到这里就结束了。希望有帮到大家,这里最主要的是如果使用数据来遍历form,就最好把getFieldDecorator写成这种格式dataName[${index}].xx


麦兜兜
15 声望3 粉丝

一个前端