一、简介
sonner 是一个轻量级的 React toast 通知库。它由 emilkowalski 开发,设计灵感来源于react-hot-toast,但在性能和用户体验上做了进一步优化。
核心特点:
- ✅ 极简 API,上手快
- ✅ 原生支持 Tailwind CSS(推荐,无需额外样式)
- ✅ 支持 Promise 自动处理(自动显示 loading → success/error)
- ✅ 高度可定制(位置、主题、动画、图标等)
- ✅ 小体积(gzip 后约 3KB)
- ✅ 支持 SSR(Next.js 友好,使用'use client'区分客户端和服务端)
- ✅ 内置无障碍(a11y)支持
二、快速开始
1. 安装
npm install sonner
# 或
yarn add sonner
注意:Sonner 依赖 React 18+ 和 Tailwind CSS(推荐但非强制)。
2. 基础用法
步骤 1:在应用根部包裹 <Toaster />
javascript
// App.tsx
import { Toaster } from 'sonner';
function App() {
return (
<>
<YourAppContent />
<Toaster /> {/* 放在最外层,确保覆盖所有内容 */}
</>
);
}
步骤 2:在组件中调用 toast
javascript
import { toast } from 'sonner';
function MyButton() {
const handleClick = () => {
toast('这是一条普通消息');
// 或
toast.success('操作成功!');
toast.error('出错了!');
toast.warning('请注意');
toast.info('提示信息');
};
return <button onClick={handleClick}>点击弹出 Toast</button>;
}
3.ExternalToast
ExternalToast 是 sonner 库中定义的一个类型,用于配置 toast 消息的显示选项。
如下,给每个方法都添加显示时长为 2500 毫秒(2.5秒),显示在屏幕顶部中央位置的设置。
TypeScript
import { ExternalToast, toast } from 'sonner';
const configuration: ExternalToast = { duration: 2500, position: 'top-center' };
const message = {
success: (msg: string) => {
toast.success(msg, configuration);
},
error: (msg: string) => {
toast.error(msg, configuration);
},
warning: (msg: string) => {
toast.warning(msg, configuration);
},
info: (msg: string) => {
toast.info(msg, configuration);
},
};
export default message;
这样设计的好处是可以统一管理所有消息的样式和行为,避免在每个调用处重复配置。
三、高级用法
1. Promise 自动处理(超实用!)
Sonner 能自动监听 Promise 状态并切换 Toast 类型:
javascript
const handleAsyncAction = () => {
toast.promise(
fetch('/api/data').then(res => res.json()),
{
loading: '正在加载...',
success: (data) => `加载成功!共 $ {data.count} 条`,
error: '请求失败,请重试',
}
);
};
✨ 这个功能极大简化了异步操作的 UI 反馈逻辑!
2. 自定义配置(全局 & 单次)
全局配置(通过 <Toaster /> props)
javascript
<Toaster
position="top-right"
richColors // 启用彩色边框(success绿色,error红色等)
expand={true}
closeButton // 显示关闭按钮
duration={3000}
/>
常用 props:
position:'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'theme:'light' | 'dark' | 'system'duration: 默认 4000msoffset: 距离边缘的偏移(如'32px')visibleToasts: 最多同时显示几个(默认 3)
单次调用配置
javascript
toast('自定义消息', {
description: '这是描述文本',
icon: '✅',
duration: 5000,
onDismiss: () => console.log('Toast 被关闭'),
});
3. 自定义 JSX 内容
Toast 内容可以是任意 React 元素:
javascript
toast.custom(
(t) => (
<div className="p-4 bg-blue-100 rounded">
<h3>自定义标题</h3>
<button onClick={() => toast.dismiss(t)}>关闭</button>
</div>
),
{ duration: Infinity } // 永不自动关闭
);
注意:
t是当前 toast 的唯一 ID,可用于手动关闭。
四、与常见库对比
表格
| 特性 | Sonner | react-hot-toast | notistack (MUI) |
|---|---|---|---|
| 体积 | ⭐ 极小 (~3KB) | 小 (~5KB) | 较大(依赖 MUI) |
| Tailwind 原生支持 | ✅ 是 | ❌ 否 | ❌ 否 |
| Promise 自动处理 | ✅ 内置 | ✅ 内置 | ❌ 需手动实现 |
| 自定义程度 | 高 | 高 | 中(受限于 MUI) |
| Next.js SSR 支持 | ✅ 完美 | ✅ 良好 | ⚠️ 需配置 |
结论:如果你用 Tailwind + React,Sonner 几乎是目前最优选择。
五、最佳实践建议
- 统一管理 Toast 调用
可封装一个useToastHook 或工具函数,避免重复配置。 - 错误提示友好化
不要直接显示后端错误码,用用户能理解的语言。 - 合理设置 duration
- 成功/信息类:3--4 秒
- 错误类:5--8 秒(或手动关闭)
- 加载中:不设 duration(由 Promise 控制)
- 避免频繁弹出
使用toast.dismiss()在新操作前清除旧 Toast,防止堆叠。