Is wrong use a parametrized function to createBrowserRouter? #9810
-
I need some context's values in some of my router loaders and I can't find a properly way to consume it since the loader isn't a hook, so what I did was:
It worked just fine, excepet that if I use // main.tsx
import { QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import React from "react";
import ReactDOM from "react-dom/client";
import { HelmetProvider } from "react-helmet-async";
import App from "./App";
import { localStorageKeys, queryClient } from "./app/configs";
import { Toaster } from "./components/ui/toaster";
import "./index.css";
import { AuthProvider } from "./services/providers/authProvider";
import { ThemeProvider } from "./services/providers/themeProvider";
import { UserProvider } from "./services/providers/userProvider";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<HelmetProvider>
<ThemeProvider defaultTheme="system" storageKey={localStorageKeys.THEME}>
<AuthProvider>
<UserProvider>
<App />
</UserProvider>
</AuthProvider>
</ThemeProvider>
</HelmetProvider>
<Toaster />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</React.StrictMode>
); // src/router/index.tsx
import { AuthLayout, RootLayout, SettingsLayout } from "@/layouts";
import PermissionLayout from "@/layouts/PermissionLayout";
import DashboardPage from "@/routes/dashboard";
import OTPPage from "@/routes/otp";
import AccountPage from "@/routes/settings/account";
import GroupCreatePage from "@/routes/settings/groups/create";
import GroupReadPage from "@/routes/settings/groups/read";
import GroupUpdatePage from "@/routes/settings/groups/update";
import SignInPage from "@/routes/sign-in";
import { grupoReadLoader, grupoUpdateLoader } from "@/services/loaders/grupo";
import { settingsLoader } from "@/services/loaders/settings";
import { GroupEnterpriseManagementProvider } from "@/services/providers/groupEnterpriseManagementProvider";
import { Role } from "@/types";
import { createBrowserRouter } from "react-router-dom";
const router = (isSignedIn: boolean, role: Role) =>
createBrowserRouter([
{
element: <AuthLayout />,
children: [
{
index: true,
path: "sign-in",
element: <SignInPage />,
},
{
path: "otp",
element: <OTPPage />,
},
],
},
{
element: <RootLayout />,
children: [
{
index: true,
element: <DashboardPage />,
},
{
path: "settings",
element: <SettingsLayout />,
loader: settingsLoader(isSignedIn, role),
children: [
{
index: true,
element: <AccountPage />,
},
{
element: <PermissionLayout allowedRoles={["OWNER"]} />,
children: [
{
path: "groups",
element: <GroupReadPage />,
loader: grupoReadLoader(isSignedIn, role),
children: [
{
path: "create",
element: <GroupCreatePage />,
},
{
path: ":id",
element: (
<GroupEnterpriseManagementProvider>
<GroupUpdatePage />
</GroupEnterpriseManagementProvider>
),
loader: grupoUpdateLoader(isSignedIn, role),
},
],
},
],
},
],
},
],
},
]);
export default router; // App.tsx
import { RouterProvider } from "react-router-dom";
import router from "./router";
import { useAuth, useUser } from "./services/hooks";
const App = () => {
const { isSignedIn } = useAuth();
const { role } = useUser();
return <RouterProvider router={router(isSignedIn, role)} />;
};
export default App; |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 7 replies
-
You will create a new router instance on each render of App, if you have any unexpected render it will trigger every loader again. The router instance is recommended to be created once when the app loads, if you need to pass the auth status and user role, it's better to get it in the loaders directly by moving them to outside React. |
Beta Was this translation helpful? Give feedback.
You will create a new router instance on each render of App, if you have any unexpected render it will trigger every loader again.
The router instance is recommended to be created once when the app loads, if you need to pass the auth status and user role, it's better to get it in the loaders directly by moving them to outside React.