• 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={{  120, marginRight: 20 }} options={selectOptions1}>
                </Select>
                <span>数据库:</span>
                <Select defaultValue="1" style={{  120, marginRight: 20 }} options={selectOptions2}>
                </Select>
                <span>表名称:</span>
                <Select defaultValue="1" style={{  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,虽然页面上确实少了一项,但是你发现第一项被复用了,给人感觉就是删除了最后一项。

  • 相关阅读:
    高并发秒杀系统架构设计 · 抢购、微信红包、一元夺宝
    Linux服务器集群系统(一)
    keepalived+nginx双机热备+负载均衡
    kafka的一些常用命令
    基于Keepalived实现LVS双主高可用集群
    如何生动形象、切中要点地讲解 OSI 七层模型和两主机传输过程
    MyBatis动态SQL foreach标签实现批量插入
    详解Vue生命周期
    centos 解压压缩包到指定目录
    门罗币(MONERO)钱包生成教程
  • 原文地址:https://www.cnblogs.com/lyt0207/p/14206354.html
Copyright © 2020-2023  润新知