React + antd 实现动态表单添加删除功能


类似下面这种功能:

 

 

 

 点击添加表增加一行,删除表删除一行,

思路:将这个表单抽成一个单独的组件,维护一个时间戳数组,这个数组的作用就是通过map循环来生成动态表单,每次点击添加就在数组里添加一个时间戳。最终遍历有几个item就渲染几个表单。

实现:

dynamic.js 动态表单 子组件

import React from 'react'; import { Select } from 'antd'; export default function DynamicForm(selectOptions1, selectOptions2) { return ( <>
            <span>业务线分组:</span>
            <Select defaultValue="1" style={{ width: 120, marginRight: 20 }} options={selectOptions1}>
            </Select>
            <span>数据库:</span>
            <Select defaultValue="1" style={{ width: 120, marginRight: 20 }} options={selectOptions2}>
            </Select>
            <span>表名称:</span>
            <Select defaultValue="1" style={{ width: 120, marginRight: 20 }} options={selectOptions2}>
            </Select>
        </>
 ); }

index.js  父组件

/* eslint-disable multiline-ternary */ import React, { useState, useEffect} from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import { Form, Input, Button, Radio, Select } from 'antd'; import {getRuleDetailApi} from '../../api/rule.api'; import '../../assets/common.less'; import dynamicForm from './DynamicForm'; const { Option } = Select; export default function AddNewMonitorRule(props) { const history = useHistory(); const location = useLocation(); const [ruleType, setRuleType] = useState(1); const [dynamicFormItem, setDynamicFormItem] = useState([]); const handleRuleTypeChange = (e) => { setRuleType(e.target.value); }; // 添加表
    const addDynamicForm = (e) => { e.preventDefault(); const newDynamicForm = dynamicFormItem.concat([Date.now()]); setDynamicFormItem(newDynamicForm); console.log(newDynamicForm); }; // 删除表
    const removeDynamicFormItem = (index) => { let tempDynamicFormItem = [...dynamicFormItem];  // 先拷贝一份,再修改,直接修改原数组react会认为是没有变化,所以页面不更新
        tempDynamicFormItem.splice(index, 1); setDynamicFormItem(tempDynamicFormItem); // setDynamicFormItem((state) => {
        // console.log(state);
        // // let tempDynamicFormItem = state.concat(); // 先拷贝一份,再修改,直接修改原数组react会认为是没有变化,所以页面不更新react中数组,如果引用地址不变,是不触发重新渲染的,但是值是设置进去了
        // state.splice(index, 1);
        // return [...state];
        // });
 };return ( <Form className="container" labelCol={{ span: 4 }} wrapperCol={{ span: 14 }}>
            <Form.Item label="表选择">
                <div> {dynamicForm(lineGropOptions, dataBaseOptions, tableNameOptions)} <Button onClick={addDynamicForm}>添加表</Button>
                </div>
                {dynamicFormItem.map((item, index) => { return ( <div key={item} style={{ marginTop: 20 }}> {dynamicForm(lineGropOptions, dataBaseOptions, tableNameOptions)} <Button onClick={() => { removeDynamicFormItem(index); }}> 删除表 </Button>
                        </div>
 ); })} </Form.Item>
        </Form>
 ); }

 

踩坑日记:

1.useState修改state数据不发生变化:

原因是在原数组上修改了,react检测不到变化,需要拷贝一份新的数组,修改完新数组,再用新数组修改state的值,也就是新旧state的引用地址必须不一样才行。

2.删除表,采用index作为key导致页面更新复用了之前的item,比如我打算删除第一个,但是因为  key = index === 0,react就会比较发现 之前和现在都有个 key === 0 的dom节点,那就会复用之前的dom,虽然页面上确实少了一项,但是你发现第一项被复用了,给人感觉就是删除了最后一项。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM