BA
Better Auth•2mo ago
Risatoga

useSession not reactive?

The useSession hook from the authentication client is not updating reactively. After the initial render, the isPending state remains true indefinitely, even after authentication is complete. The component only refreshes its state when there's a code change that forces a re-render. const { data: session, isPending } = authClient.useSession(); Even after authentication is complete, the component doesn't update to show the user as logged in until the file is saved or another action triggers a re-render.
34 Replies
NeuhljebTihomir
NeuhljebTihomir•2mo ago
This is issue a lot of people face: https://github.com/better-auth/better-auth/issues/1006
GitHub
useSession() not always triggering a state change · Issue #1006 ·...
Is this suited for github? Yes, this is suited for github To Reproduce Sign in with email and password Use useSession() in the following component: export function AuthLayout({ children }: AppLayou...
NeuhljebTihomir
NeuhljebTihomir•2mo ago
Solution is to replace authClient.useSession() with custom hook useAuthSession(): import { authClient } from "@/lib/auth-client"; import { useEffect, useRef } from "react"; function useAuthSession() { const { data, isPending, error, //error object refetch, } = authClient.useSession(); // Track the latest value of isPending const isPendingRef = useRef(isPending); useEffect(() => { isPendingRef.current = isPending; }, [isPending]); useEffect(() => { if (isPending) { const timerNotify = setTimeout(() => { if (isPendingRef.current) { refetch(); // sends another get-session request to the server //authClient.$store.notify("$sessionSignal"); // or this poke store to trigger a re-render } }, 2500); // after 2.5 seconds of pending, force resetting client store const timerReload = setTimeout(() => { if (isPendingRef.current) { window.location.reload(); } }, 5000); // after 5 seconds of pending, reload the page return () => { clearTimeout(timerNotify); clearTimeout(timerReload); }; } }, [isPending]); return { data, isPending, error, }; } export default useAuthSession;
Risatoga
RisatogaOP•2mo ago
pff.... not sure I want to do this "trick"... this is actually quite a fundamental part of the library, and I am now a bit concerned about it being buggy. 🫠
bekacru
bekacru•2mo ago
We know it's a fundamental part of the library, and we're trying to figure out what the issue is but still couldn't reproduce it on our end. None of the people have provided a reproducible example I could look at yet. If you can create one, I'd love to take a look.
mediacrafters
mediacrafters•2mo ago
we're facing the same issue using authclient only when signing up with credentials. @bekacru I saw you posted a client-only demo here is there a way to see the code? maybe that will help us solve our issue. P.S. using google "sing up" updates my session correctly.
GitHub
useSession() not always triggering a state change · Issue #1006 ·...
Is this suited for github? Yes, this is suited for github To Reproduce Sign in with email and password Use useSession() in the following component: export function AuthLayout({ children }: AppLayou...
Risatoga
RisatogaOP•2mo ago
I know I know. Indeed I tried to reproduced it for you and got no issues what-so-ever, but it's still a problem that it happens...!
bekacru
bekacru•2mo ago
mediacrafters
mediacrafters•2mo ago
@bekacru thanks! I see you have client.useSession() inside the same component you are calling signIn.email. In my case I have a header component inside my layout that calls client.useSession(), and signIn.email() is called in a component inside a specific page. If you have time, can you try a similar structure to see if you can reproduce the bug?
bekacru
bekacru•2mo ago
GitHub
better-auth/demo/nextjs/app/client-test/page.tsx at fix/use-session...
The most comprehensive authentication framework for TypeScript - better-auth/better-auth
GitHub
better-auth/demo/nextjs/components/wrapper.tsx at fix/use-session ·...
The most comprehensive authentication framework for TypeScript - better-auth/better-auth
mediacrafters
mediacrafters•2mo ago
is this new version deployed here? https://demo.better-auth.com/client-test If it is, I'm not seeing the avatar component in the header when I log in, which means that <UserAvatar /> is returning null
Better Auth
Better Auth
The most comprehensive authentication library for typescript
bekacru
bekacru•2mo ago
No it's not deployed. Try to clone the repo and run it locally.
Risatoga
RisatogaOP•2mo ago
Hi there! any update regarding the useSession bug?
bekacru
bekacru•2mo ago
not really. but the moment someone provides me a reproduction it'll be fixed :))
Risatoga
RisatogaOP•2mo ago
I was just creating a "boilerplate" for myself and I am getting the error there. Is a bit heavy, but on lighter tries to reproduce it...it was just not happening. Somehow it gets messed up when the codebase is bigger. I can share it if that's ok just... know that is not a "minimal reproduction" (but it's just a boilerplate)
bekacru
bekacru•2mo ago
yeah sure that works
Risatoga
RisatogaOP•2mo ago
https://github.com/RicSala/trabajo-veterinaria.git here is the repo I have cleaned a bit because I am using the "better-auth-ui" package too, and everything was a bit "mingled" but I think it's clear enough try to change organizations several times back and forth, and you will see that the useSession hook randome gets stuck in a previous render
bekacru
bekacru•2mo ago
Thanks! Will let you know. couldn't still recreate it :((( could you please send me a screen recording of what happens?
Risatoga
RisatogaOP•2mo ago
I was about to do it yesterday. It does not ALWAYS happen, but it happens often enough to be a problem. let me record that.
Risatoga
RisatogaOP•2mo ago
Area — Screen Studio
Area — Created and shared with Screen Studio
Risatoga
RisatogaOP•2mo ago
I just create a component to switch organizations and as you can see, the session is not updating and it's just printing the session as it comes from the hook:
Risatoga
RisatogaOP•2mo ago
No description
Risatoga
RisatogaOP•2mo ago
hope it helps
bekacru
bekacru•2mo ago
oh didn't know this was connected to the org plugin. the issue here is changing org doesn't trigger session refetch. It was jsut assumed the user is using useActiveOrganization instead. And it only triggers the active session refetch. Someone also pointed this out to me and I updated it earlier today. Update to 1.2.5-beta.4 this should be fixed. But Im still not sure if this is the same issue mentioned on the gh issue thread
Risatoga
RisatogaOP•2mo ago
I would say it's not, as in previous ocasions I think I was not using th org plugin... Will keep an eye on it and come back here whenever I spot it again
mediacrafters
mediacrafters•2mo ago
I just tried 1.2.5-beta.4 and the bug is still there, I'll try to create a small POC to see if you can reproduce it I added you as a collaborator in my repo, it's called better-auth-poc. Check your github
bekacru
bekacru•2mo ago
could you make it public? and also would appreciate a screen recording
mediacrafters
mediacrafters•2mo ago
just made it public and added the screen recording to the readme
bekacru
bekacru•2mo ago
link?
mediacrafters
mediacrafters•2mo ago
check your DM
bekacru
bekacru•2mo ago
Just figured out the root issue here. Thanks for the repro by @mediacrafters It's due to object reference and destructuring. If you try to use a destructured object from the auth client, you need to use the destructured useSession instead of authClient.useSession and vice versa.
const authClient = createAuthClient();
const { signIn, useSession } = authClient;

// Method 1: Using destructured methods - This works
signIn(...);
useSession();
// When you use both destructured methods together, the session updates properly


// Method 2: Using direct object methods - This works too
authClient.signIn(...);
authClient.useSession();
// When you use both direct object methods together, the session updates properly


// Method 3: Mixing styles - This breaks! :x:
authClient.signIn(...);
useSession();
// When you mix direct object access with destructured methods, it breaks because it disrupts the object reference needed to trigger atoms.
// We'll try to investigate on how we potentially support them interchangeably. But we'll document this in the meantime
const authClient = createAuthClient();
const { signIn, useSession } = authClient;

// Method 1: Using destructured methods - This works
signIn(...);
useSession();
// When you use both destructured methods together, the session updates properly


// Method 2: Using direct object methods - This works too
authClient.signIn(...);
authClient.useSession();
// When you use both direct object methods together, the session updates properly


// Method 3: Mixing styles - This breaks! :x:
authClient.signIn(...);
useSession();
// When you mix direct object access with destructured methods, it breaks because it disrupts the object reference needed to trigger atoms.
// We'll try to investigate on how we potentially support them interchangeably. But we'll document this in the meantime
Risatoga
RisatogaOP•2mo ago
This is big news!!!
Kabeer
Kabeer•2mo ago
// Method 2: Using direct object methods - This works too
authClient.signIn(...);
authClient.useSession();
// Method 2: Using direct object methods - This works too
authClient.signIn(...);
authClient.useSession();
I was using this across the code base , but still had the same problem Currenly my fix - calling refetch in root wrapper (seems to work)
export default function AppWrapper({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const { data, isPending, refetch } = authClient.useSession();

useLayoutEffect(() => {
useSettings.persist.rehydrate();
refetch(); // <- Added This
}, []);

console.log(isPending);

return (
<>
<Navbar/>
{children}
{isPending && <PageLoader />}
</>
);
}
function PageLoader() {
return (
<div className="fixed inset-0 z-50 grid place-items-center">
<div className="bg-foreground/40 absolute inset-0 backdrop-blur-xs" />
<LoaderCircle
className="text-border relative z-50 animate-spin"
size={70}
/>
</div>
);
}
export default function AppWrapper({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const { data, isPending, refetch } = authClient.useSession();

useLayoutEffect(() => {
useSettings.persist.rehydrate();
refetch(); // <- Added This
}, []);

console.log(isPending);

return (
<>
<Navbar/>
{children}
{isPending && <PageLoader />}
</>
);
}
function PageLoader() {
return (
<div className="fixed inset-0 z-50 grid place-items-center">
<div className="bg-foreground/40 absolute inset-0 backdrop-blur-xs" />
<LoaderCircle
className="text-border relative z-50 animate-spin"
size={70}
/>
</div>
);
}
Col' ✦
Col' ✦•6d ago
Hey guys, do we have a propper fix for this issue ? My session is still not updating when i sign in/ sign out in my next js app...
bekacru
bekacru•6d ago
have you checked the above solution. making sure if you're distructing the authclient, you should always keep distructing

Did you find this page helpful?