Component: Toast.jsx & useToast.jsx
Relevant source files
The following files were used as context for generating this wiki page:
The QR-Tool application utilizes a custom notification system to provide non-intrusive feedback to the user. This system is composed of two primary parts: the useToast.jsx custom React hook, which manages the state and logic for all toast notifications, and the Toast.jsx component, which is the presentational component responsible for rendering a single toast message.
This architecture provides a decoupled and reusable way to trigger notifications from any component in the application. A single ToastContainer is rendered at the root level in App.jsx, and other components, such as ExportPanel.jsx, can invoke the showToast function provided by the hook to display messages related to actions like successful downloads, validation errors, or other user feedback.
Sources: src/App.jsx:5, 273, src/components/ExportPanel.jsx, README.md
Architecture Overview
The toast system's architecture is centered around the useToast hook. This hook acts as a centralized manager for an array of toast objects. It exposes a showToast function to add new notifications and a ToastContainer component to render them. The ToastContainer iterates through the active toasts and renders an individual Toast component for each one.
The following diagram illustrates the relationship between these parts.
This diagram shows how the App component initializes the useToast hook and renders the ToastContainer. Other components can then call the showToast function to add notifications, which are managed in the hook's internal state and rendered by the container.
Sources: src/hooks/useToast.jsx, src/App.jsx:273, 1449, src/components/ExportPanel.jsx:100-106
useToast.jsx Hook
This hook encapsulates all the logic for managing and displaying toast notifications.
State Management
The hook maintains an internal state variable named toasts, which is an array of toast objects. Each object in the array represents a single notification to be displayed.
Sources: src/hooks/useToast.jsx:8
A toast object has the following structure:
id: A unique identifier, generated usingDate.now().message: The string content of the notification.type: The type of toast (info,success,warning,error), which determines its styling.duration: The time in milliseconds before the toast automatically closes.
Sources: src/hooks/useToast.jsx:12
Core Functions
The hook returns an object containing the showToast function and the ToastContainer component.
-
showToast(message, type = 'info', duration = 5000)
This function is used to trigger a new notification. It creates a new toast object with a unique ID and adds it to thetoastsstate array.
Sources: src/hooks/useToast.jsx:10-14 -
removeToast(id)
An internal function used to remove a toast from the state array by itsid. This is typically called when a toast is closed, either by the user or automatically after its duration expires.
Sources: src/hooks/useToast.jsx:16-18 -
ToastContainer
This is a memoized React component returned by the hook. It is responsible for rendering the list of active toasts. It maps over thetoastsstate array and renders a<Toast>component for each item, passing the necessary props, including anonClosecallback that is bound to theremoveToastfunction.
Sources: src/hooks/useToast.jsx:20-33
Data Flow Diagram
The sequence diagram below shows the typical flow when a toast is created and subsequently closed.
Toast.jsx Component
This is a presentational component that renders a single toast notification.
Props
The component accepts the following props:
| Prop | Type | Default | Description |
|---|---|---|---|
message | string | - | The message to be displayed in the toast. |
type | string | 'info' | The type of toast, controlling its color and icon. |
onClose | func | - | Callback function to be executed when the toast is closed. |
duration | number | 5000 | Duration in milliseconds before the toast automatically closes. |
| Sources: src/components/Toast.jsx:9 |
Auto-Close Logic
The component uses a useEffect hook to handle the auto-close functionality. If the duration prop is greater than 0, it sets a setTimeout that calls the onClose prop after the specified duration. A cleanup function is returned to clear the timer if the component unmounts before the timer fires.
// src/components/Toast.jsx:11-16
React.useEffect(() => {
if (duration > 0) {
const timer = setTimeout(onClose, duration);
return () => clearTimeout(timer);
}
}, [duration, onClose]);
Sources: src/components/Toast.jsx:11-16
Styling and Types
The appearance of the toast is determined by the type prop. The component contains two objects, styles and icons, that map the type to specific Tailwind CSS classes and emoji icons.
The supported types are:
info(ℹ️)success(✅)warning(⚠️)error(❌)
Sources: src/components/Toast.jsx:18-29
Accessibility
For accessibility, the toast div has role="alert" and aria-live="assertive". This ensures that screen readers will announce the notification to the user as soon as it appears.
Sources: src/components/Toast.jsx:33-34
Usage Example in App.jsx and ExportPanel.jsx
The toast system is integrated into the application to provide feedback for various user actions.
Initialization
In the main App.jsx component, the useToast hook is called to retrieve the showToast function and the ToastContainer component. The ToastContainer is then rendered at the top level of the component tree, ensuring it is always present to display notifications.
// src/App.jsx:273
export default function App() {
const { showToast, ToastContainer } = useToast();
// ...
return (
// ...
<ToastContainer />
</div>
);
}
Sources: src/App.jsx:273, 1449
Triggering Toasts
Components trigger toasts by calling the showToast function. For example, the ExportPanel component receives an onError function as a prop. In App.jsx, this prop is connected to the showToast function.
When a user attempts to download a QR code, the ExportPanel calls this function to report success or failure.
// In App.jsx, passing showToast to ExportPanel
<ExportPanel
// ...
onError={(message, type) => showToast(message, type, 5000)}
/>
// In ExportPanel.jsx, calling the onError prop
// ...
if ((isSVG && !srcSVG) || (!isSVG && !srcCanvas)) {
onError?.('Không tìm thấy QR code để tải xuống', 'error');
// ...
}
// ...
onError?.(`✓ Đã tải xuống ${ext.toUpperCase()}`, 'success');
Sources: src/App.jsx:1441-1443, src/components/ExportPanel.jsx:28-31, 59
Another example is in App.jsx itself, where showToast is used to display validation errors when a user uploads a logo file that is too large or has an unsupported format.
// src/App.jsx:643-650
const maxSize = 4 * 1024 * 1024; // 4MB
if (file.size > maxSize) {
showToast(
`❌ File quá lớn! Kích thước: ${(file.size / 1024 / 1024).toFixed(1)} MB. Giới hạn: 4 MB. Vui lòng chọn file nhỏ hơn.`,
'error',
6000,
);
return;
}
Sources: src/App.jsx:643-650
Conclusion
The toast notification system, comprising the useToast hook and Toast component, provides a robust and decoupled mechanism for user feedback in the QR-Tool application. By centralizing state management in the hook and separating the presentation into a dedicated component, the system is easy to use from anywhere in the component tree. This is demonstrated by its use in handling file export statuses in ExportPanel.jsx and input validation feedback in App.jsx, contributing to a more interactive and user-friendly experience.