This introduce you to a toast api with Material UI, or MUI.
If you want to use a toast with MUI, <Snackbar />
component is the option.
https://mui.com/material-ui/react-snackbar/#main-content
However, it's annoying to apply it for every single case where a local state, like showToast: boolean
, is required to toggle the component.
In that case, you want a toast api, right?
In order for realizing it, a toast context is an option.
Create ToastProvider
First, let's create a context provider which wraps the <Snackbar />
.
The point is to create useToast()
as a hook. It enables us to call it from any components.
import { Alert, AlertColor, Snackbar } from '@mui/material';
import React, { createContext, ReactNode, useContext, useState } from 'react';
type ToastProp = {
message: string;
type?: AlertColor;
duration?: number;
};
type ToastContextType = {
toast: (props: ToastProp) => void;
};
const ToastContext = createContext<ToastContextType>({
toast: () => undefined,
});
export const useToast = () => {
return useContext(ToastContext);
};
export const ToastContextProvider = ({ children }: { children: ReactNode }) => {
const [open, setOpen] = useState(false);
const [message, setMessage] = useState('');
const [type, setType] = useState<AlertColor>('success');
const [duration, setDuration] = useState<number>(0);
const handleClose = () => {
setOpen(false);
};
const toast = ({ message, type = 'success', duration = 5000 }: ToastProp) => {
setMessage(message);
setType(type);
setDuration(duration);
setOpen(true);
};
const contextValue = { toast };
return (
<ToastContext.Provider value={contextValue}>
<>
{children}
<Snackbar
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
open={open}
autoHideDuration={duration}
onClose={handleClose}
>
<Alert severity={type} sx={{ width: '100%' }}>
{message}
</Alert>
</Snackbar>
</>
</ToastContext.Provider>
);
};
export default ToastContext;
Set ContextProvider to App.tsx
Then, set it up in the root component like App.tsx
in React.
import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { ToastContextProvider } from './components/ToastProvider';
import Index from '@/pages/Index';
import NotFound from '@/pages/NotFound';
function App() {
return (
<ToastContextProvider>
<Routes>
<Route path="/" element={<Index />}>
<Route path="*" element={<NotFound />} />
</Routes>
</ToastContextProvider>
);
}
export default App;
Call it in components
Now, you can call the hook from any components.
import React, { useEffect } from 'react';
import { useToast } from '@/components/ToastProvider';
export default function HandbookRegistration() {
const { toast } = useToast();
useEffect(() => {
if (status.isSuccess) { // Please use your own toggle status.
toast({ message: 'Success' });
}
if (status.isError) {
toast({ message: 'Error' });
}
}, [status]);
return <div>sample</div>;
}
That's it.