useToaster()
API
The useToaster()
hook provides you a headless system that will manage the notification state for you. This makes building your own notification system much easier.
It solves the following problems for you:
- Built-in dispatch system with
toast()
- Handlers to pause toasts on hover
- Automatically remove expired toasts
- Support for unmount animations. Removal is delayed by 1s, but sets
visible
on the toast tofalse
.
Importing from headless
You can import only the core of the library with react-hot-toast/headless
. It won't include any styles, dependencies or custom components.
import { useToaster } from 'react-hot-toast/headless';
Be aware: react-hot-toast 2.0 adds support for custom render functions, an easier method to render custom notification components.
It's recommended to only have one <Toaster/>
or useToaster()
in your app at a time. If you need the current state without the handlers, you should use useToasterStore()
instead.
Usage with React Native
Headless mode is perfectly suited to add notifications to your React Native app. You can check out this example.
Examples
Basic Example
import toast, { useToaster } from 'react-hot-toast/headless';const Notifications = () => {const { toasts, handlers } = useToaster();const { startPause, endPause } = handlers;return (<div onMouseEnter={startPause} onMouseLeave={endPause}>{toasts.filter((toast) => toast.visible).map((toast) => (<div key={toast.id} {...toast.ariaProps}>{toast.message}</div>))}</div>);};// Create toasts anywheretoast('Hello World');
Animated Example
Instead of mapping over visibleToasts
we'll use toasts
, which includes all hidden toasts. We animate them based on toast.visible
. Toasts will be removed from 1 second after being dismissed, which give us enough time to animate.
You can play with the demo on CodeSandbox.
import { useToaster } from 'react-hot-toast/headless';const Notifications = () => {const { toasts, handlers } = useToaster();const { startPause, endPause, calculateOffset, updateHeight } = handlers;return (<divstyle={{position: 'fixed',top: 8,left: 8,}}onMouseEnter={startPause}onMouseLeave={endPause}>{toasts.map((toast) => {const offset = calculateOffset(toast, {reverseOrder: false,gutter: 8,});const ref = (el) => {if (el && typeof toast.height !== "number") {const height = el.getBoundingClientRect().height;updateHeight(toast.id, height);}};return (<divkey={toast.id}ref={ref}style={{position: 'absolute',width: '200px',background: 'papayawhip',transition: 'all 0.5s ease-out',opacity: toast.visible ? 1 : 0,transform: `translateY(${offset}px)`,}}{...toast.ariaProps}>{toast.message}</div>);})}</div>);};