Remix Toast
用於 React router v7 / Remix.run 的簡單伺服器端 toast 管理函式庫!
此函式庫為您提供向使用者顯示 toast 通知所需的所有基本工具。客戶端實作完全由您決定,您可以使用任何您想要顯示 toast 的函式庫。
伺服器函數使用 @remix-run/server-runtime 基本元件來建立 cookie session,因此此函式庫與伺服器無關,應適用於任何伺服器設定。
如果您想深入了解其運作方式,可以在此處找到:https://alemtuzlak.hashnode.dev/handling-toasts-in-remix
安裝
npm install remix-toast
Remix.run
如果您正在使用 Remix.run,您可以使用此函式庫的 v1.2.2 或更低版本。 v2 及更高版本僅與 react-router v7 相容。
遷移到 react-router v7 的指南
如果您正在使用 react-router v7,則可以使用此函式庫的 v2.0.0 版本。您唯一需要變更的是將所有 json
方法重新命名為 data
方法,redirect 方法保持不變。例如
- import { jsonWithSuccess } from "remix-toast";
+ import { dataWithSuccess } from "remix-toast";
export const action = () => {
- return jsonWithSuccess({ result: "Data saved successfully" }, "Operation successful! 🎉");
+ return dataWithSuccess({ result: "Data saved successfully" }, "Operation successful! 🎉");
};
設定
伺服器端
為了能夠在應用程式中的任何位置顯示 toast,您需要在您的 root.tsx
檔案中加入以下程式碼。
import { getToast } from "remix-toast";
export const loader = async ({ request }: LoaderFunctionArgs) => {
// Extracts the toast from the request
const { toast, headers } = await getToast(request);
// Important to pass in the headers so the toast is cleared properly
return data({ toast }, { headers });
}
export default function App({ children }: { children: ReactNode }) {
const { toast } = useLoaderData<typeof loader>();
useEffect(() => {
if(toast){
// Call your toast function here
alert(toast.message);
}
}, [toast])
return (
...
);
}
客戶端
之後,您可以使用任何您喜歡的 toast 通知函式庫,但以下是一些範例
react-toastify
import { data, type LinksFunction, type LoaderFunctionArgs } from "react-router";
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useLoaderData } from "react-router";
import { useEffect } from "react";
import { getToast } from "remix-toast";
import { ToastContainer, toast as notify } from "react-toastify";
import toastStyles from "react-toastify/ReactToastify.css?url";
// Add the toast stylesheet
export const links: LinksFunction = () => [{ rel: "stylesheet", href: toastStyles }];
// Implemented from above
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { toast, headers } = await getToast(request);
return data({ toast }, { headers });
};
export default function App() {
const { toast } = useLoaderData<typeof loader>();
// Hook to show the toasts
useEffect(() => {
if (toast) {
// notify on a toast message
notify(toast.message, { type: toast.type });
}
}, [toast]);
return (
<html lang="en">
<head>
...
</head>
<body>
...
{/* Add the toast container */}
<ToastContainer />
</body>
</html>
);
}
Sonner
import { data, type LinksFunction, type LoaderFunctionArgs } from "react-router";
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useLoaderData } from "react-router";
import { useEffect } from "react";
import { getToast } from "remix-toast";
import { Toaster, toast as notify } from "sonner";
// Implemented from above
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { toast, headers } = await getToast(request);
return data({ toast }, { headers });
};
export default function App() {
const { toast } = useLoaderData<typeof loader>();
// Hook to show the toasts
useEffect(() => {
if (toast?.type === "error") {
notify.error(toast.message);
}
if (toast?.type === "success") {
notify.success(toast.message);
}
}, [toast]);
return (
<html lang="en">
<head>...</head>
<body>
...
{/* Add the toast container */}
<Toaster />
</body>
</html>
);
}
覆寫 cookie 選項
您可以使用 setToastCookieOptions
函式傳入您自己的選項來覆寫預設 cookie 選項。
import { setToastCookieOptions } from "remix-toast";
setToastCookieOptions({
secrets:
process.env.NODE_ENV === "production"
? [process.env.SESSION_SECRET]
: ["secret"]
});
使用自訂 session 建立公用程式函數
createToastUtilsWithCustomSession
是一個函數,可讓您為您的 toast 建立自訂 session。如果您想為應用程式的不同部分設定不同類型的 toast,這非常有用。
import { createCookieSessionStorage } from "react-router";
import { createToastUtilsWithCustomSession } from "remix-toast";
const session = createCookieSessionStorage({
cookie: {
name: "your-custom-session",
secrets: ["some-secret"],
},
});
export const {
getToast,
redirectWithToast,
redirectWithSuccess,
redirectWithError,
redirectWithInfo,
redirectWithWarning,
dataWithSuccess,
dataWithError,
dataWithInfo,
dataWithWarning
} = createToastUtilsWithCustomSession(session);
公用程式
redirectWithToast
通用函數,可讓您重新導向至新路由並顯示 toast 訊息。
import { redirectWithToast } from "remix-toast";
export const action = () => {
return redirectWithToast("/login", { message: "You need to login to access this page", description: "description of toast", type: "error" });
}
redirectWithSuccess
重新導向至新路由並顯示成功 toast 訊息。
import { redirectWithSuccess } from "remix-toast";
export const action = () => {
return redirectWithSuccess("/login", "You are logged in!");
//or with description and message (works for all the other utilities as well)
return redirectWithSuccess("/login", { message: "You are logged in!", description: "description of toast" });
}
redirectWithError
重新導向至新路由並顯示錯誤 toast 訊息。
import { redirectWithError } from "remix-toast";
export const action = () => {
return redirectWithError("/login", "You need to login to access this page");
}
redirectWithInfo
重新導向至新路由並顯示資訊 toast 訊息。
import { redirectWithInfo } from "remix-toast";
export const action = () => {
return redirectWithInfo("/login", "You need to login to access this page");
};
redirectWithWarning
重新導向至新路由並顯示警告 toast 訊息。
import { redirectWithWarning } from "remix-toast";
export const action = () => {
return redirectWithWarning("/login", "You need to login to access this page");
};
dataWithSuccess
顯示成功 toast 訊息而不重新導向。
import { dataWithSuccess } from "remix-toast";
export const action = () => {
return dataWithSuccess({ result: "Data saved successfully" }, "Operation successful! 🎉");
//or with description and message (works for all the other utilities as well)
return dataWithSuccess({ result: "Data saved successfully" }, { message: "Operation successful! 🎉", description: "description of toast" });
};
dataWithError
顯示錯誤 toast 訊息而不重新導向。
import { dataWithError } from "remix-toast";
export const action = () => {
return dataWithError(null, "Oops! Something went wrong. Please try again later.");
};
dataWithInfo
顯示資訊 toast 訊息而不重新導向。
import { dataWithInfo } from "remix-toast";
export const action = () => {
return dataWithInfo({ info: "Additional information" }, "Your profile has been successfully updated.");
};
dataWithWarning
顯示警告 toast 訊息而不重新導向。
import { dataWithWarning } from "remix-toast";
export const action = () => {
return dataWithWarning({ warning: "Potential issues" }, "Your session is about to expire.");
};
謝謝
如果您想支持這個專案,可以透過給這個儲存庫加星號並與您的朋友分享來做到。
感謝這個專案的所有貢獻者和對社群的支持。你們太棒了!