Complete React integration examples with hooks and components
Try the React integration in action:
npm install modern-toasts
import toast from 'modern-toasts';
// In your component
function MyComponent() {
const handleClick = () => {
toast.success('Hello from React!');
};
return (
<button onClick={handleClick}>
Show Toast
</button>
);
}
// hooks/useToast.js
import toast from 'modern-toasts';
import { useCallback } from 'react';
export const useToast = () => {
const showSuccess = useCallback((message, options) => {
return toast.success(message, options);
}, []);
const showError = useCallback((message, options) => {
return toast.error(message, options);
}, []);
const showInfo = useCallback((message, options) => {
return toast.info(message, options);
}, []);
const showWarning = useCallback((message, options) => {
return toast.warning(message, options);
}, []);
const dismiss = useCallback((id) => {
toast.dismiss(id);
}, []);
const dismissAll = useCallback(() => {
toast.dismissAll();
}, []);
return {
showSuccess,
showError,
showInfo,
showWarning,
dismiss,
dismissAll
};
};
import { useToast } from './hooks/useToast';
function UserProfile() {
const { showSuccess, showError } = useToast();
const handleSave = async () => {
try {
await saveUserProfile();
showSuccess('Profile saved successfully!');
} catch (error) {
showError('Failed to save profile. Please try again.');
}
};
return (
<button onClick={handleSave}>
Save Profile
</button>
);
}
// components/ToastProvider.jsx
import React, { createContext, useContext, useCallback } from 'react';
import toast from 'modern-toasts';
const ToastContext = createContext();
export const ToastProvider = ({ children, config = {} }) => {
// Configure toast on mount
React.useEffect(() => {
toast.configure({
position: 'bottom-right',
maxVisibleStackToasts: 3,
enableBorderAnimation: true,
enableFillAnimation: true,
...config
});
}, [config]);
const showToast = useCallback((type, message, options = {}) => {
return toast[type](message, options);
}, []);
const value = {
success: (msg, opts) => showToast('success', msg, opts),
error: (msg, opts) => showToast('error', msg, opts),
info: (msg, opts) => showToast('info', msg, opts),
warning: (msg, opts) => showToast('warning', msg, opts),
dismiss: toast.dismiss,
dismissAll: toast.dismissAll,
configure: toast.configure
};
return (
<ToastContext.Provider value={value}>
{children}
</ToastContext.Provider>
);
};
export const useToastContext = () => {
const context = useContext(ToastContext);
if (!context) {
throw new Error('useToastContext must be used within ToastProvider');
}
return context;
};
// App.jsx
import { ToastProvider } from './components/ToastProvider';
function App() {
return (
<ToastProvider config={{ position: 'top-right' }}>
<div className="App">
<Header />
<Main />
<Footer />
</div>
</ToastProvider>
);
}
import { useToast } from './hooks/useToast';
function ContactForm() {
const { showError, showSuccess } = useToast();
const [formData, setFormData] = useState({});
const handleSubmit = async (e) => {
e.preventDefault();
// Validation
if (!formData.email) {
showError('Email is required');
return;
}
if (!formData.message) {
showError('Message is required');
return;
}
try {
await submitForm(formData);
showSuccess('Message sent successfully!', {
autoDismiss: 5000
});
setFormData({});
} catch (error) {
showError('Failed to send message. Please try again.');
}
};
return (
<form onSubmit={handleSubmit}>
{/* form fields */}
</form>
);
}
import { useToast } from './hooks/useToast';
function DataFetcher() {
const { showError, showInfo } = useToast();
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const fetchData = async () => {
setLoading(true);
showInfo('Loading data...', { autoDismiss: 2000 });
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const result = await response.json();
setData(result);
} catch (error) {
if (error.name === 'AbortError') {
showError('Request was cancelled');
} else if (error.message.includes('404')) {
showError('Data not found');
} else if (error.message.includes('500')) {
showError('Server error. Please try again later.');
} else {
showError('Network error. Check your connection.');
}
} finally {
setLoading(false);
}
};
return (
<div>
<button onClick={fetchData} disabled={loading}>
{loading ? 'Loading...' : 'Fetch Data'}
</button>
</div>
);
}
import { useToast } from './hooks/useToast';
function UserActions() {
const { showSuccess, showWarning, showInfo } = useToast();
const handleLike = () => {
showSuccess('â¤ī¸ Liked!', { autoDismiss: 2000 });
};
const handleShare = () => {
navigator.clipboard.writeText(window.location.href);
showInfo('đ Link copied to clipboard!');
};
const handleDelete = () => {
showWarning('â ī¸ This action cannot be undone!', {
autoDismiss: 0, // Persistent warning
showCloseButton: true
});
};
return (
<div>
<button onClick={handleLike}>Like</button>
<button onClick={handleShare}>Share</button>
<button onClick={handleDelete}>Delete</button>
</div>
);
}
// Configure globally in your app
toast.configure({
position: 'bottom-right',
maxVisibleStackToasts: 4,
defaultDuration: 4000,
enableBorderAnimation: true,
enableFillAnimation: true,
pauseBackgroundToastsOnHover: true,
animationDirection: 'left-to-right',
customCSS: `
.toast-container {
z-index: 9999;
}
.toast-custom {
border-radius: 12px;
}
`
});
// Custom styled toasts
const showCustomToast = () => {
toast.success('Custom styled toast!', {
backgroundColor: '#1f2937',
textColor: '#f9fafb',
borderColor: '#10b981',
className: 'my-custom-toast',
icon: 'đ',
autoDismiss: 5000
});
};
// types/toast.ts
import { ToastType, ToastOptions } from 'modern-toasts';
interface CustomToastOptions extends ToastOptions {
userId?: string;
trackingId?: string;
}
export const useTypedToast = () => {
const showSuccess = (
message: string,
options?: CustomToastOptions
): string => {
return toast.success(message, options);
};
// ... other methods
return { showSuccess };
};