react+antd动态增删表单方式
作者:赵乘风_i
这篇文章主要介绍了react+antd动态增删表单方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
最近开发的一个功能,和之前写过的很像,但毕竟我也快两年经验了,当然不能再使用原来实现的方法,于是,又搞起来。
功能
需要对多个Input组成的list可以新增和删除
在之前的文章 react 涉及的增加,删除list ,我说不可以使用 index
来做删除,就使用了 给每个 list 添加 selfId
的方式来实现删除。
然而事实是可以使用 index 来进行删除操作的。
当年我才疏学浅,没有get到高级玩法,使用selfId
这样的实现,无疑就是对数据过度操作了,所以学习了新的使用方法,实现如下:
技术栈: react hooks + antd Form
实现原理
其实新增还是不变的,在list后新增一个空对象,让其多一条数据,再重新渲染。
删除有所改变,首先,form 表单的 key, 学习官方的demo,经过一番改良,
使用 data.0.name1 这样的格式作为 某个表单的 key, 那么根据form的机制,会自动产生
data: [{name1: 'xx'}]
这样的数据格式,所以刚好也不用我们再次处理了。
然后说回删除
// 获取当前的所有表单值 const lists = getFieldValue(formTitle); // 删除后替换 for (let index in lists) { const nIndex = Number(index); if (nIndex >= i && lists[nIndex + 1]) { formData.map(item => setFieldsValue({[`${formTitle}.${nIndex}.${item}`]: lists[nIndex + 1][item]})); } } // 删除数组数据 setDetail([...detail.slice(0, i), ...detail.slice(i, detail.length - 1)]);
再来详细说一下:
1、获取当前的所有表单值,是为了等会执行表单替换
2、循环这个表单list值,再找出删除的这个index,然后把后面的表单重新赋值,往前移动一个
3、删除一个数组的长度
整体实现
import React, { Fragment } from 'react'; import { Form, Input, Radio, Icon, message, Button } from 'antd'; const { TextArea } = Input; const formItemLayout = { labelCol: { span: 5 }, wrapperCol: { span: 16 }, }; const FormItemList = (props) => { const { form } = props; const { getFieldDecorator, getFieldValue, setFieldsValue } = form; const [detail, setDetail] = React.useState([]); const formData = ['name1', 'name2', 'name3', 'name4']; const formTitle = 'data'; React.useEffect(() => { setDetail(data) }, []); const deleteOne = (i) => { const lists = getFieldValue(formTitle); for (let index in lists) { const nIndex = Number(index); if (nIndex >= i && lists[nIndex + 1]) { formData.map(item => setFieldsValue({[`${formTitle}.${nIndex}.${item}`]: lists[nIndex + 1][item]})); } } setDetail([...detail.slice(0, i), ...detail.slice(i, detail.length - 1)]); } const newItem = () => { setDetail([...detail, {}]); }; return ( <Fragment> {detail.map((item, index) => ( <div style={{ background: '#eee', position: 'relative', marginBottom: 10 }}> <div key={item.key}> <Form.Item label="字段名称1" {...formItemLayout}> {getFieldDecorator(`${formTitle}.${index}.${formData[0]}`, { rules: [{ required: true, message: '请填写'}], initialValue: item[formData[0]], })(<Input maxLength={8} placeholder="请填写" />)} </Form.Item> <Form.Item label="字段名称2" {...formItemLayout}> {getFieldDecorator(`${formTitle}.${index}.${formData[1]}`, { rules: [{ required: true, message: '请填写'}], initialValue: item[formData[1]], })(<Input maxLength={8} placeholder="请填写" />)} </Form.Item> <Form.Item label="字段名称3" {...formItemLayout}> {getFieldDecorator(`${formTitle}.${index}.${formData[2]}`, { rules: [{ required: true, message: '请选择'}], initialValue: item[formData[2]], })(<Input maxLength={8} placeholder="请填写" />)} </Form.Item> <Form.Item label="字段名称4" {...formItemLayout}> {getFieldDecorator(`${formTitle}.${index}.${formData[3]}`, { initialValue: item[formData[3]], })(<Input maxLength={8} placeholder="请填写" />)} </Form.Item> </div> {detail && detail.length > 1 && <div style={{ position: 'absolute', top: 5, right: 5, fontSize: 20, }}> <Icon type="close" onClick={() => deleteOne(index)}/> </div> } </div> ))} {detail && detail.length < 5 && <Button style={{ width: '100%', marginTop: 8 }} type="dashed" icon="plus" onClick={newItem} >添加</Button>} </Fragment> ); }; export default Form.create()(FormItemList);
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。