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));
    }
  };
相关推荐
半个落月34 分钟前
LangChain.js Agent Memory 实战(下):用 Milvus 构建可检索的长期记忆
javascript·langchain
半个落月34 分钟前
LangChain.js Agent Memory 实战(上):从内存对话、文件持久化到截断与摘要
javascript·langchain
Nicander1 小时前
我给 Excalidraw 做了一个本地工作区:DrawSpace
前端·开源
linux_cfan3 小时前
17 · 引擎适配器全景:HLS/DASH/Vimeo/Mux/Cast
前端·javascript·音视频
计算机魔术师4 小时前
烧掉2780亿美元还不够?OpenAI的资本豪赌让人头皮发麻
前端
IT_陈寒4 小时前
Java线程池用错参数,我的服务居然悄悄崩溃了
前端·人工智能·后端
神秘的猪头5 小时前
React 脱围机制(二):重新理解 useEffect——它不是生命周期,而是同步外部系统
react.js
卡布鲁5 小时前
React useMemo 与 useCallback 完全指南:原理、场景与避坑
前端·react.js
碳基修炼5 小时前
排查记:本地 devServer 是 http,浏览器却把 302 重定向升级成了 https
前端·http
步行cgn5 小时前
Spring p 命名空间注入详解
java·前端·spring