一、简介
Sonner 是一个固执己见的 React Toast 组件。如果你的项目不依赖大型的组件库,但是你有需要一个 Toast 快速完成任务。我想 Sonner 特别适合你的项目。

二、流行度

sonner 在 npm 的下载量已经达到 11K+, 在 github 的 star 已经 5.4K 足以看出 Sonner 是一个受欢迎的 React 库。
三、Sonner 的基本用法
3.1)安装
sh
npm install sonner
3.2)基础用法
- 将组件挂在在目标位置,一般是根组件位置
tsx
<Toaster /> // 默认
<Toaster expand /> // 展开 richColors
<Toaster expand richColors /> // 展开且指定颜色
- 使用函数调用方使用 toast
ts
toast('Hello World!')
toast.success('Event has been created')
四、Sonner 库工程化
Sonner 选用技术栈:
- TypeScript
- Next.js
- Vercel
- Turbo
- tsup
- playwright
- pnpm workspace
- ...
五、tsup 构建源代码
sh
import { defineConfig } from 'tsup';
export default defineConfig({
minify: true,
target: 'es2018',
external: ['react'],
sourcemap: true,
dts: true,
format: ['esm', 'cjs'],
injectStyle: true,
});
tsup 构建 src 目录下的源代码文件。构建 sonner 源代码
sh
pnpm i
pnpm run build # tsup 构建 src/index.tsx 文件 到 dist 目录
注意:sonner 中部分代码标记为 'use client';
表示在客户端渲染为好。
六、turbo 的基本用法
sh
pnpm add turbo --globa # 全局安装
pnpm dlx create-turbo@latest # turbo cli 的用法
turbo dev
turbo dev --filter docs
turbo build
turbo lint
对于 turbo 这里仅仅是常用命令进行说明,--filter
是指定 pnpm workspace 中的包名字。
七、sonner 文档构建
Sonner 文档基于 nextra
构建, nextra 简单、强大且灵活的网站生成框架。
八、测试
test 也是一个单独的 nextjs 项目,它基于 @playwright/test
九、sonner 源码与发布订阅模式
Sonner 源码有一些值得学习的地方
- 发布订阅模式在 React 中的实践
- 函数调用产生 dom 结构与 React 结合实践
十、整体思路
大致流程:Sonner 中实现了 Observer 观察对象,观察者对象中维护了两个队列:subscribers 和 toasts 分别用于发布订阅和状态管理。React 组件中订阅 Observer 对象,并绑定组件自己的 state。使用方法是,在调用 toast 方法时候,添加数据到 Observer 实例中,并通知订阅者,更新组件 state 状态。
10.1)观察对象
ts
class Observer {
subscribers: Array<(toast: ExternalToast | ToastToDismiss) => void>;
toasts: Array<ToastT | ToastToDismiss>;
constructor() {
this.subscribers = [];
this.toasts = [];
}
subscribe() {} // 订阅方法
addToast() {}
dismiss() {}
create(data) {}
// 其他
}
export const ToastState = new Observer();
const toastFunction = (message: string | React.ReactNode, data?: ExternalToast) => {
ToastState.addToast();
//
};
10.2)观察对象React 组件中订阅
ts
React.useEffect(() => {
return ToastState.subscribe((toast) => {
// 订阅中设置 组件内部 state
});
}, []);
10.3)观察对象toast 函数调用
ts
toast('My first toast')
toast 函数会调用 addToast 方法,在 Observer 实例中添加 toast, 然后遍历所有的订阅者。更新 React state 数据。当然后可以多次调用,因为 toast 状态维护在队列中。
十一、小结
Sonner 适合没有依赖大型组件库,但是需要一个 toast 组件的项目,Sonner 本身使用发布订阅模式实现。对前端封装组件有一定的借鉴意义。