用好Popconfirm气泡确认组件的正确姿势与避坑指南

欧阳晓英 组件 阅读 2,165
赞 27 收藏
二维码
手机扫码查看
反馈

我的写法,亲测靠谱

Popconfirm这个组件我用得挺多的,尤其是在一些需要二次确认的操作场景下。它比普通的Modal更轻量,也比Confirm更灵活。分享一下我常用的写法:

用好Popconfirm气泡确认组件的正确姿势与避坑指南

import { Popconfirm, message } from 'antd';

function handleDelete() {
  message.success('删除成功');
}

<Popconfirm
  title="确定要删除这条记录吗?"
  onConfirm={handleDelete}
  okText="确认"
  cancelText="取消"
  placement="topRight"
>
  <button>删除</button>
</Popconfirm>

这段代码有几个关键点要说一下:placement我一般会设置为topRight,这样气泡会出现在按钮右上方,用户体验比较好。另外okText和cancelText一定要明确写出来,不要用默认值,因为不同项目可能会有不同的文案规范。

这里还有个容易忽略的地方:onConfirm回调里最好不要直接写业务逻辑,而是调用一个单独的方法,就像上面的handleDelete一样。这样的好处是方便做单元测试,也能让代码结构更清晰。

这几种错误写法,别再踩坑了

先说几个我踩过的坑吧。最常见的是有人会这样写:

<Popconfirm
  title="确定要删除吗?"
  onConfirm={() => deleteRecord(id)}
>
  <button>删除</button>
</Popconfirm>

这种写法问题很大,特别是当组件重新渲染时,id可能已经变了,但回调里的id还是旧的。我之前就遇到过这种情况,删错数据了,差点被老板打死。

还有一种常见的错误是不处理异步操作:

<Popconfirm
  title="确定要提交吗?"
  onConfirm={async () => await submitForm()}
>
  <button>提交</button>
</Popconfirm>

这样写会有个问题:如果submitForm失败了,用户也不知道发生了什么。正确的做法是加上错误处理:

const handleSubmit = async () => {
  try {
    await submitForm();
    message.success('提交成功');
  } catch (error) {
    message.error('提交失败,请重试');
  }
};

<Popconfirm
  title="确定要提交吗?"
  onConfirm={handleSubmit}
>
  <button>提交</button>
</Popconfirm>

实际项目中的坑

在真实项目中,我发现有几点特别需要注意。首先是样式问题,有时候Popconfirm的位置会跑偏,特别是在复杂的布局中。解决方法是在父容器上加relative定位:

.popconfirm-wrapper {
  position: relative;
}

另一个大坑是和表单验证一起用的时候。比如你有个表单,想在提交前做个确认,这时候要注意:

<Form onFinish={async (values) => {
  const isConfirmed = await new Promise((resolve) => {
    confirm({
      title: '确认提交吗?',
      onOk: () => resolve(true),
      onCancel: () => resolve(false),
    });
  });

  if (!isConfirmed) return;

  // 正常提交逻辑
}}>

这个写法虽然能work,但不够优雅。更好的方案是自己封装一个支持Promise的Popconfirm组件。

还有个细节要注意:当Popconfirm包裹的内容是一个自定义组件时,记得给组件加上displayName,不然Antd的校验会报warning。

小技巧分享

分享几个实用的小技巧。第一个是动态修改提示文案,比如根据不同的状态显示不同的确认内容:

<Popconfirm
  title={status === 'draft' ? '保存草稿?' : '发布文章?'}
  onConfirm={handleAction}
>
  <button>{status === 'draft' ? '保存' : '发布'}</button>
</Popconfirm>

第二个技巧是处理频繁触发的情况。有些场景下用户可能会连续点击多次,导致多次触发onConfirm,可以通过防抖来解决:

import debounce from 'lodash/debounce';

const handleConfirm = debounce(() => {
  // 确认逻辑
}, 300);

<Popconfirm
  title="确定要执行吗?"
  onConfirm={handleConfirm}
>
  <button>执行</button>
</Popconfirm>

结尾总结

以上就是我在使用Popconfirm过程中积累的一些实战经验。从基本用法到各种踩坑经历,都是真金白银换来的教训。虽然这些经验不一定适用于所有场景,但至少能给大家提供一些参考。

如果你有更好的实践方案,或者发现了文中的问题,欢迎在评论区交流讨论。前端开发就是这样,总能在互相学习中进步。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论

暂无评论