-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Description
Reproduction
import { Outlet } from "react-router";
import Navbar from "@/modules/navbar/Navbar.tsx";
import { ScrollY } from "@/modules/shared/components/Scroll.tsx";
import GlobalNavigateLoader from "@/modules/navbar/GlobalNavigateLoader.tsx";
import type { Route } from "./+types/RootLayout.ts";
import type { LoaderFunctionArgs } from "react-router";
import type { Session } from "@backend/types/user.type.ts";
import { fetchApi } from "@/bff/lib/absolutefetch.ts";
import { MyContextProviderZustand } from "@/modules/auth/context/MyContextProviderZustand.tsx";
async function getSession(request: Request) {
// Get auth state from cookies or session
const response = await fetchApi("/api/auth/get-session", {
method: "GET",
headers: request.headers,
});
const session = (await response.json()) as Session | null;
console.log("getSession response:", session);
return session;
}
export async function loader({ request }: LoaderFunctionArgs) {
const session = await getSession(request);
return session;
}
export function shouldRevalidate() {
return false;
}
function RootLayout({ loaderData }: Route.ComponentProps) {
return (
<MyContextProviderZustand initialSession={loaderData}>
<GlobalNavigateLoader />
<Navbar />
<ScrollY className="app-screen">
<Outlet />
</ScrollY>
</MyContextProviderZustand>
);
}
export default RootLayout;
import Wrapper from "@/modules/shared/components/Wrapper.tsx";
import { useSession } from "../../auth/context/MyContextProviderZustand.tsx";
function Home() {
const session = useSession();
return <Wrapper>{session ? <div>{session.user.name}</div> : <span>Not logged in</span>}</Wrapper>;
}
export default Home;
As you can see here im importing MyContextProviderZustand.tsx with
- deno import map "@/": "./app/" and with a relative import path
This is MyContextProviderZustand.tsx
import type { Session } from "@backend/types/user.type.ts";
import { createStore, useStore } from "zustand";
import { createContext, useContext, useRef } from "react";
type MyActionsType = {
setSession: (session: Session | null) => void;
};
type MyStateType = {
session: Session | null;
actions: MyActionsType;
};
type ZustandStore = ReturnType<typeof createZustandStore>;
const createZustandStore = (initialSession: Session | null) => {
return createStore<MyStateType>()((set) => ({
session: initialSession,
actions: {
setSession: (session: Session | null) => set(() => ({ session })),
},
}));
};
const ZustandContext = createContext<ZustandStore | null>(null);
function MyContextProviderZustand({
children,
initialSession = null,
}: {
children: React.ReactNode;
initialSession?: Session | null;
}) {
const storeRef = useRef<ZustandStore>(null);
if (!storeRef.current) {
storeRef.current = createZustandStore(initialSession);
}
return <ZustandContext.Provider value={storeRef.current}>{children}</ZustandContext.Provider>;
}
function useMyContextZustand<T>(selector: (state: MyStateType) => T): T {
const store = useContext(ZustandContext);
if (!store) {
throw new Error("useMyContextZustand must be used within a MyContextProviderZustand");
}
return useStore(store, selector);
}
function useSession() {
return useMyContextZustand((s) => s.session);
}
export { MyContextProviderZustand, useMyContextZustand, useSession };
System Info
System:
OS: Windows 10 10.0.19044
CPU: (28) x64 Intel(R) Core(TM) i7-14700K
Memory: 19.68 GB / 31.77 GB
Binaries:
Node: 22.14.0 - C:\Program Files\nodejs\node.EXE
npm: 10.9.2 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Chromium (131.0.2903.70)
Internet Explorer: 11.0.19041.5794Used Package Manager
npm
Expected Behavior
When i import a file with either the import map or the relative import path it should reference the same file and also just bundle the code one time because like for this context its important to have the same reference because it will throw useMyContextZustand must be used within a MyContextProviderZustand
Actual Behavior
It bundles two times the same code into the bundle and for this context provider its fatal
it creates const ZustandContext = createContext(null);
and it creates const ZustandContext$1 = createContext(null);
so when using the hook it wont use the correct one and will throw the useMyContextZustand must be used within a MyContextProviderZustand error