ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

在 Refine 中集成 react-toastify:自定义 Notification Provider 完整实战指南

2026/9/10 1:32:11 拓冰建站 浏览量
在 Refine 中集成 react-toastify:自定义 Notification Provider 完整实战指南 在 Refine 中集成 react-toastify自定义 Notification Provider 完整实战指南【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine导读本文以开源仓库 refine 中的官方博文 How to create a notification provider with react-toastify 为主体结合packages/core中通知模块的源码实现系统讲解如何在 Refine 应用中用 react-toastify 从零搭建一套自定义通知系统。读完本文你将掌握Refine 通知 Provider 的open/close接口契约、useNotificationHook 的调用方式、undoable 可撤销模式下的进度通知组件以及懒加载、toast 限流等性能优化手段。为什么 Refine 需要一套通知系统对于 admin panel、dashboard、内部工具这类数据密集型前端应用而言一个可靠的通知系统几乎是刚需当数据库发生增删改等变更时用户需要及时得到反馈尤其在分布式系统场景下这种反馈能有效避免用户对操作是否成功产生困惑。Refine 生态为 Material UI、Chakra UI、Ant Design、Mantine 等设计系统内置了开箱即用的通知 Provider。但如果内置实现无法满足你的定制需求Refine 允许通过notificationProvider属性传入任意自定义实现——这正是 react-toastify 等 toast 库发挥价值的场景。Refine 通知架构NotificationProvider 接口契约在 Refine 中通知 Provider 本质上是一个包含open与close两个方法的对象。该契约在源码 packages/core/src/contexts/notification/types.ts 中定义export type OpenNotificationParams { key?: string; message: string; type: success | error | progress; description?: string; cancelMutation?: () void; undoableTimeout?: number; }; export interface INotificationContext { open?: (params: OpenNotificationParams) void; close?: (key: string) void; } export type NotificationProvider RequiredINotificationContext;核心字段说明字段类型必填说明messagestring是通知中展示的文案typesuccess \| error \| progress是通知类型progress专用于 undoable 模式keystring否通知的唯一标识用于更新或关闭指定通知descriptionstring否通知的补充描述cancelMutation() void否undoable 模式下取消变更的回调undoableTimeoutnumber否undoable 模式下的可撤销倒计时秒接口类型可以从refinedev/core直接导入无需自行声明import { NotificationProvider } from refinedev/core;open方法何时被调用当用户执行了需要通知的操作如更新、删除记录时Refine 会调用 Provider 的open方法。其参数为OpenNotificationParams对象message与type为必填其余可选。type决定通知形态——成功操作显示 success 通知、失败操作显示 error 通知、undoable 模式显示 progress 进度通知。close方法按 key 关闭通知与open相对close方法接收通知的key参数用于关闭指定通知。useNotificationHook组件内触发通知要在组件内主动触发通知需要使用useNotificationHook。其实现位于 packages/core/src/hooks/notification/useNotification/index.ts本质是从NotificationContext中取出open与closeimport { useNotification } from refinedev/core; const { open, close } useNotification(); // 打开通知 open?.({ key: notification-key, type: success, message: Successfully updated Blog Post, description: This is a success message, }); // 关闭通知 close?.(notification-key);值得注意的是Refine 的数据 Hook如useUpdate、useDelete内部还会通过 useHandleNotification 统一调用open——它会先检查successNotification/errorNotification配置再决定调用open或回退到默认通知文案这正是编辑记录后自动弹出操作成功/失败提示的底层机制。认识 react-toastify 的核心构件react-toastify 是 React 生态中流行的 toast 通知库MIT 许可、开源免费。它的两大核心构件是ToastContainer组件负责渲染并定位所有 toast通过 props 配置位置、主题、自动关闭等行为toast对象函数式 API调用即触发通知。ToastContainer常用 props 示例ToastContainer positiontop-right autoClose{5000} hideProgressBar{false} newestOnTop{false} closeOnClick rtl{false} pauseOnFocusLoss draggable pauseOnHover themelight /toast函数接收消息文本与配置对象toast(Successfully updated blog post, { position: top-left, autoClose: 5000, hideProgressBar: false, closeOnClick: true, pauseOnHover: true, draggable: true, progress: undefined, theme: light, });注意通过toast函数传入的选项优先级高于ToastContainer的 props。实战用 react-toastify 搭建自定义通知 Provider前置创建 Refine 项目并安装依赖你可以用 Refine CLI 创建项目也可以直接在浏览器中通过 refine.new 平台生成后下载选择 Vite Headless UI REST API 即可。项目就绪后安装依赖并启动开发服务器npm install npm run dev开发服务器默认运行在localhost:5173。接下来安装 react-toastifynpm install react-toastify第一步实现基础版 notificationProvider在src下创建providers/notificationProvider.tsximport React from react; import { NotificationProvider } from refinedev/core; import { toast } from react-toastify; export const notificationProvider: NotificationProvider { open: ({ key, message, type, undoableTimeout, cancelMutation }) { if (toast.isActive(key as React.ReactText)) { toast.update(key as React.ReactText, { render: message, type: default, }); return; } toast(message, { toastId: key, type: default, }); }, close: (key: any) toast.dismiss(key), };这里用到了 react-toastify 的三个关键 APItoast.isActive(key)传入通知 key返回布尔值判断该通知是否处于激活状态toast.update(key, options)若指定 key 的通知已激活则原地更新其内容而不是创建新通知避免同一操作重复弹窗toast.dismiss(key)按 key 关闭通知完美映射close方法。第二步接入 Refine 组件在App.tsx中导入 Provider、ToastContainer与样式文件并把 Provider 传给Refine的notificationProvider属性import { ToastContainer } from react-toastify; import { notificationProvider } from ./providers/notificationProvider; import react-toastify/dist/ReactToastify.min.css; function App() { return ( BrowserRouter Refine ... notificationProvider{notificationProvider} i18nProvider{i18nProvider} ... Routes Route element{ Layout Outlet / ToastContainer / /Layout } ... /Route /Routes UnsavedChangesNotifier / /Refine /BrowserRouter ); }ToastContainer必须挂载在组件树中通知才能被渲染。完成这一步后编辑或新建博客文章时Refine 就会自动弹出通知。第三步支持 undoable 模式的进度通知Refine 支持三种变更mutation模式通过Refine组件的options属性配置const App: React.FC () { return ( Refine ... options{{ mutationMode: optimistic }} / ); };pessimistic默认先执行变更成功后才更新 UI 并跳转optimistic本地立即应用变更并更新 UI无论成败失败时再弹出错误通知undoable本地立即应用变更并更新 UI随后等待可配置的倒计时窗口期间用户可取消变更、回滚 UI。undoable 模式下Refine 会调用open方法并传入type: progress、undoableTimeout倒计时秒数与cancelMutation取消变更的回调。其底层由 packages/core/src/components/undoableQueue/index.tsx 驱动——它通过setTimeout每 1000ms 派发一次DECREASE_NOTIFICATION_SECOND逐秒递减剩余秒数直至为 0 时执行变更。因此我们需要一个能展示倒计时与Undo按钮的自定义组件。创建src/component/undoable-notification/index.tsxtype UndoableNotification { message: string; cancelMutation?: () void; closeToast?: () void; }; export const UndoableNotification: React.FCUndoableNotification ({ closeToast, cancelMutation, message, }) { return ( div p{message}/p button onClick{() { cancelMutation?.(); closeToast?.(); }} Undo /button /div ); };按钮点击时依次调用cancelMutation撤销变更与closeToast关闭 toast。React-toastify 会自动向自定义内容组件注入closeToast属性。第四步升级 Provider按 type 分发渲染将UndoableNotification引入 Provider并重写open方法以区分progress与普通通知。仓库中 examples/with-react-toastify/src/providers/notificationProvider.tsx 提供了完整可运行的最终实现import React from react; import type { NotificationProvider } from refinedev/core; import { toast } from react-toastify; import { UndoableNotification } from ../components/undoableNotification; export const notificationProvider: NotificationProvider { open: ({ key, message, type, undoableTimeout, cancelMutation }) { if (type progress) { if (toast.isActive(key as string | number)) { toast.update(key as string | number, { progress: undoableTimeout (undoableTimeout / 10) * 2, render: ( UndoableNotification message{message} cancelMutation{cancelMutation} / ), type: default, }); } else { toast( UndoableNotification message{message} cancelMutation{cancelMutation} /, { toastId: key, updateId: key, closeOnClick: false, closeButton: false, autoClose: false, progress: undoableTimeout (undoableTimeout / 10) * 2, }, ); } } else { if (toast.isActive(key as string | number)) { toast.update(key as string | number, { render: message, closeButton: true, autoClose: 5000, type, }); } else { toast(message, { toastId: key, type, }); } } }, close: (key) toast.dismiss(key), };要点拆解progress 分支autoClose: false让 toast 常驻closeButton: false隐藏关闭按钮进度条用progress: undoableTimeout (undoableTimeout / 10) * 2按秒数换算百分比若该 key 已激活则用toast.update原地刷新进度与倒计时文案普通分支已激活的通知更新为成功/失败样式并设置autoClose: 5000未激活则新建 toasttype直接透传给 react-toastifysuccess/error与其内置类型一一对应toastId/updateId均设为 key保证更新操作能精准定位到同一条通知。验证效果编辑一条记录即可预览通知效果把options.mutationMode切换为undoable后可看到带倒计时进度条和 Undo 按钮的自定义通知。仓库中的 examples/blog-react-toastify 与 examples/with-react-toastify 都是可以直接运行验证的完整示例工程。通知性能优化实践随着应用规模增长通知系统也需要性能考量以下是博文总结的四个方向1. 懒加载 react-toastify第三方库体积可观时可用React.lazy按需加载ToastContainer降低首屏加载时间import React, { lazy, Suspense } from react; const ToastContainer lazy(() import(react-toastify).then((module) ({ default: module.ToastContainer, })), ); function App() { return ( Suspense fallback{divLoading.../div} ToastContainer / {/* Other components */} /Suspense ); }2. 控制并发 toast 数量高频通知场景下连续渲染大量 toast 会造成性能瓶颈。用固定toastId去重并用limit限制同屏数量import { toast } from react-toastify; function notify() { if (toast.isActive(my-toast-id)) return; toast(New message received!, { toastId: my-toast-id, // 固定 ID 防止重复 toast autoClose: 3000, limit: 3, // 限制同屏 toast 数量 }); }3. 按重要级定制自动关闭时长非关键通知用更短autoClose保持界面清爽、降低内存占用关键通知用更长时长保证用户能看到import { toast } from react-toastify; function notify() { // 低优先级通知 toast.info(Information message, { autoClose: 2000, }); // 高优先级通知 toast.error(Error occurred!, { autoClose: 8000, }); }4. 监控通知渲染性能利用onOpen回调配合console.time建立简单的渲染耗时监控及早发现性能劣化console.time(Toast Render Time); toast.success(Operation successful!, { onOpen: () console.timeEnd(Toast Render Time), });仓库内可继续深挖的资料通知契约类型定义packages/core/src/contexts/notification/types.tsuseNotificationHook 实现packages/core/src/hooks/notification/useNotification/index.tsundoable 倒计时驱动逻辑packages/core/src/components/undoableQueue/index.tsx完整可运行示例examples/with-react-toastify/src/providers/notificationProvider.tsx 与 examples/with-react-toastify/src/App.tsx官方 Notification Provider 文档documentation/docs/notification/notification-provider/index.md结语通知系统是复杂分布式业务应用中不可或缺的一环。Refine 在 Material UI、Chakra UI、Mantine 等设计系统上提供了健壮且可定制的内置通知能力而当内置实现无法满足需求时通过实现open/close两个方法、配合 react-toastify 的toast.isActive、toast.update、toast.dismiss等 API即可在半小时内打造出支持 success/error/progress 三种形态、可撤销、可性能调优的自定义通知 Provider——这正是 Refine 通知架构约定简单、扩展自由的设计精髓。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考