react+antd中做一个外部按钮新增 表格内部本地新增一条数据并且支持编辑删除(无难度上手)

需求背景

做一个可以外部控制新增刷新表格 表格内部可以编辑删除 类似下方需求图

实现过程

因为我实现时有两个这样的表格 所以我的事件里面会有传参用于判断 可忽略传参判断部分 代码中有formatMessage部分为国际化可忽略

javascript 复制代码
 <div style={{ marginBottom: '10px', marginTop: '10px', display: 'flex' }}>
          <Button type={'primary'} onClick={() => handleAddWhiteList(1)}>
            {formatMessage({ id: 'button.Add' })}
          </Button>

          <Button
            type={'primary'}
            style={{ marginLeft: '10px' }}
            onClick={() => onRefreshWhiteList(1)}
            icon={<SyncOutlined />}
          />
        </div>
        <Table
          size="small"
          columns={whiteColumns}
          dataSource={whiteDataSource}
          pagination={false}
          bordered={true}
          rowKey={'id'}
          scroll={{
            y: whiteDataSource?.length > 3 ? 55 * 3 : undefined, // 动态计算高度
          }}
        />


//js部分
  const [whiteDataSource, setWhiteDataSource] = useState([]);
  //白名单列表
  const whiteColumns = [
    {
      title: 'HOST',
      dataIndex: 'url',
      render: (text, record) => {
        return (
          <Input
            value={record.url}
            disabled={record.disabled}
            onBlur={(e) => handleUrlBlur(e, record.id, 1)}
            onChange={(e) => handleUrlWhitleChange(e, record.id, 1)}
            placeholder={formatMessage({ id: 'label.rollCall.PleaseEnter' })}
          />
        );
      },
    },
    {
      title: formatMessage({ id: 'label.Operation' }),
      dataIndex: 'operation',
      width: 120,
      render: (text, record) => {
        return (
          <Space size={'middle'}>
            <TableButton
              onClick={() => handleEdit(1, record)}
              disabled={!record.disabled}
              icon={
                <IconBtn
                  itemInfo={{ itemId: 'edit', title: formatMessage({ id: 'button.Edit' }) }}
                />
              }
            />

            <TableButton
              confirm
              confirmMsg={formatMessage({ id: 'confirm.Delete' })}
              onConfirm={() => handleDel(1, record)}
              icon={
                <IconBtn
                  itemInfo={{ itemId: 'delete', title: formatMessage({ id: 'button.Delete' }) }}
                />
              }
            />
          </Space>
        );
      },
    },
  ];
  const handleAddWhiteList = (num) => {
    if (num == 1) {
      setWhiteDataSource([
        ...whiteDataSource,
        { url: '', id: Date.now(), disabled: false, error: null },
      ]);
    } else {
      setBlackDataSource([
        ...blackDataSource,
        { url: '', id: Date.now(), disabled: false, error: null },
      ]);
    }
  };
  const onRefreshWhiteList = (num) => {
    if (num == 1) {
      setWhiteDataSource(whiteDataSource.filter((item) => item.url !== ''));
    } else {
      setBlackDataSource(blackDataSource.filter((item) => item.url !== ''));
    }
  };
  //名单失焦事件
  const handleUrlBlur = (e, id, num) => {
    if (num == 1) {
      const newData = whiteDataSource.map((item) => {
        if (item.id === id) {
          return { ...item, disabled: true };
        }
        return item;
      });
      setWhiteDataSource(newData);
    } else {
      const newData = blackDataSource.map((item) => {
        if (item.id === id) {
          return { ...item, disabled: true };
        }
        return item;
      });
      setBlackDataSource(newData);
    }
  };
  //名单输入事件
  const handleUrlWhitleChange = (e, id, num) => {
    if (num == 1) {
      const newData = whiteDataSource.map((item) => {
        if (item.id === id) {
          return { ...item, url: e.target.value };
        }
        return item;
      });
      setWhiteDataSource(newData);
    } else {
      const newData = blackDataSource.map((item) => {
        if (item.id === id) {
          return { ...item, url: e.target.value };
        }
        return item;
      });
      setBlackDataSource(newData);
    }
  };
//  编辑处理函数
  const handleEdit = (num, record) => {
    if (num == 1) {
      setWhiteDataSource((prev) =>
        prev.map((item) => (item.id === record.id ? { ...item, disabled: false } : item)),
      );
    } else {
      setBlackDataSource((prev) =>
        prev.map((item) => (item.id === record.id ? { ...item, disabled: false } : item)),
      );
    }
  };
  //删除处理
  const handleDel = (num, record) => {
    if (num == 1) {
      setWhiteDataSource((prev) => prev.filter((item) => item.id !== record.id));
    } else {
      setBlackDataSource((prev) => prev.filter((item) => item.id !== record.id));
    }
  };
相关推荐
云水一下1 小时前
从零开始!VMware安装Fedora Workstation 44桌面系统完整教程
前端
小码哥_常2 小时前
安卓黑科技:实现多平台商品详情页一键跳转APP
前端
killerbasd2 小时前
还是迷茫 5.3
前端·react.js·前端框架
不会敲代码13 小时前
TCP/IP 与前端性能:从数据包到首次渲染的底层逻辑
前端·tcp/ip
kyriewen3 小时前
奥特曼借GPT-5.5干杯,而你的Copilot正按Token收钱
前端·github·openai
AC赳赳老秦3 小时前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
kyriewen3 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
不会敲代码14 小时前
从零搭建 AI 日记助手:用 Milvus 向量数据库实现语义搜索
javascript·openai
千寻girling4 小时前
《 Git 详细教程 》
前端·后端·面试
threelab5 小时前
Three.js UV 图像变换效果 | 三维可视化 / AI 提示词
javascript·人工智能·uv