Create toasts from outside of React Components
Mingming Ma
Posted on April 1, 2024
This week, I submitted a PR to ChatCraft that added an alert function using the Standalone Toasts feature of Chakra UI. I previously used the useToast
hooks, but I found that the Standalone Toasts are the solution when hooks can't be used. I'd like to share how I implemented it.
Standalone Toasts
Firstly, let's see the examples from Chakra UI document
import * as ReactDOM from 'react-dom/client'
import { createStandaloneToast } from '@chakra-ui/react'
const { ToastContainer, toast } = createStandaloneToast()
// render the ToastContainer in your React root
const rootElement = document.getElementById('root')
ReactDOM.createRoot(yourRootElement).render(
<>
<App />
<ToastContainer />
</>,
)
toast({
title: 'An error occurred.',
description: 'Unable to create user account.',
status: 'error',
duration: 9000,
isClosable: true,
})
At first glance, I found it a little confusing because it seems like we need to add the ToastContainer somewhere.
// render the ToastContainer in your React root
const rootElement = document.getElementById('root')
ReactDOM.createRoot(yourRootElement).render(
<>
<App />
<ToastContainer />
</>,
)
Actually, if your project already has @chakra-ui/react
installed, then we don't need to import it separately. What we need becomes to :
import { createStandaloneToast } from '@chakra-ui/react'
const { toast } = createStandaloneToast()
toast({
title: 'An error occurred.',
description: 'Unable to create user account.',
status: 'error',
duration: 9000,
isClosable: true,
})
How I did in the PR
//utils.ts
/**
* Only meant to be used outside components or hooks
* where useAlert cannot be used.
*/
import type { AlertArguments } from "../hooks/use-alert";
export const utilizeAlert = async () => {
const { createStandaloneToast } = await import("@chakra-ui/react");
const { toast } = createStandaloneToast();
const info = ({ id, title, message }: AlertArguments) => {
toast({
id,
title,
description: message,
colorScheme: "blue",
status: "info",
position: "top",
isClosable: true,
duration: 3000,
});
};
const loading = ({ id, title, message }: AlertArguments) => {
const fallbackId = new Date().toISOString();
toast({
id: id ?? fallbackId,
title,
description: message,
colorScheme: "blue",
status: "loading",
position: "top",
isClosable: true,
duration: null,
});
return id ?? fallbackId;
};
const closeLoading = (id: string) => {
toast.close(id);
};
return {
info,
loading,
closeLoading,
};
};
As you can see, I wrap different kinds of toasts in the utilizeAlert
function. Then we can show the alert by:
import { utilizeAlert } from "./utils";
const nonComponentFunction () {
const { info , loading, closeLoading } = await utilizeAlert();
//show info alert
info({title: "this is info alert"})
//show loading alert
const alertId = loading({
title: `Generating image, please wait.`,
});
//some stuff
//close loading alert
closeLoading(alertId);
}
Standalone Toasts are a good design pattern that allows users to create toasts outside of a component. Sometimes it's good to have more options, and I think that's one of the reasons why Chakra UI is so popular. So that's it. I hope you found this helpful. Thanks for reading!
Posted on April 1, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024