stormy-gold
stormy-gold6mo ago

useIsAuthenticated infinite re-renders

I had a v3 app with a very simple, custom auth provider. Things were working. I migrated to v4 (just created a new project and started porting code over). I scaffolded it from the refine install. It created a sample authProvider. But when I swapped in my revised custom auth provider, the app became unresponsive. Eventually traced it to useIsAuthenticated causes continuous rerendering of the component in which I call it. I reveted to the authprovider the refine seed project provided and modified its check method so that it always returns {authenticated: true}. Same thing, it just keeps rerending the component. If it returns {authenticated: false}, the app redirects to the login page. Main question is whether this is a known issue? Any hints?
6 Replies
kapa.ai
kapa.ai6mo ago
Hi @jorge_92765. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the extracts, there's no mention of a known issue with useIsAuthenticated causing infinite re-renders. However, the behavior you're experiencing might be due to how you're using the hook or how your authProvider is set up. Here are a few things you could check: 1. Check your authProvider setup: Ensure that your authProvider is correctly set up and that the check method is properly implemented. The check method should return a promise that resolves to an object with an authenticated property. If the user is authenticated, authenticated should be true, otherwise, it should be false. If authenticated is false, you can also include a redirectTo property to specify where to redirect unauthenticated users. Here's an example of how it could look:
const authProvider: AuthBindings = {
// ...
check: async () => {
if (localStorage.getItem("email")) {
return {
authenticated: true,
};
}
return {
authenticated: false,
error: {
message: "Check failed",
name: "Not authenticated",
},
logout: true,
redirectTo: "/login",
};
},
};
const authProvider: AuthBindings = {
// ...
check: async () => {
if (localStorage.getItem("email")) {
return {
authenticated: true,
};
}
return {
authenticated: false,
error: {
message: "Check failed",
name: "Not authenticated",
},
logout: true,
redirectTo: "/login",
};
},
};
Source (https://refine.dev/docs/tutorial/understanding-authprovider/create-authprovider#check) 2. Check how you're using useIsAuthenticated: Ensure that you're using the useIsAuthenticated hook correctly. This hook should be used in a component that needs to check if the user is authenticated. It returns an object with isLoading, data, and error properties. You should handle these properties appropriately to prevent unnecessary re-renders. Here's an example of how you could use it:
import { useIsAuthenticated } from "@refinedev/core";

export const Authenticated: React.FC = ({ children }) => {
const { isLoading, data } = useIsAuthenticated();

if (isLoading) {
return <div>loading...</div>;
}

if (data.error) {
return null;
}

if (data.authenticated) {
return <>{children}</>;
}

return null;
};
import { useIsAuthenticated } from "@refinedev/core";

export const Authenticated: React.FC = ({ children }) => {
const { isLoading, data } = useIsAuthenticated();

if (isLoading) {
return <div>loading...</div>;
}

if (data.error) {
return null;
}

if (data.authenticated) {
return <>{children}</>;
}

return null;
};
Source (https://refine.dev/docs/migration-guide/auth-provider#auth-hooks) If you're still experiencing issues, it might be helpful to refer to the Refine documentation (https://refine.dev/docs) or seek help from the Refine community. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai6mo ago
<@1189331277116088451> kapa.ai is still learning and improving, please let us know how it did by reacting below
stormy-gold
stormy-gold6mo ago
Yes, I used the sample auth provider and just modified it to always return authenticated as true. Yes, I am using it in that way. I get the response that it is authenticated. But it just keeps rerendering the component going into an infinite loop. Ok, so turns out I don't need to do that check in my component. I gather the top-level route is guarding the inner routes. And I guess calling useIsAuthenticated again within the inner route makes things go a bit crazy (unlike in v3). I probably missed something in the docs. Seems like an easy pitfall...
plain-purple
plain-purple6mo ago
Hey @jorge_92765 👋 , when did you migrate from v3 to v4? Couple of weeks ago we released an update to the <Authenticated /> component which now requires a key prop. (Check out the explanation of the changelog for more info on why and how to update https://github.com/refinedev/refine/releases/tag/%40refinedev%2Fcore%404.46.0) This might be the underlying issue with the useIsAuthenticated, back in the older versions <Authenticated /> had some internal logic that alters the useIsAuthenticated and was sometimes conflicting with it when its used inside <Authenticated />. Happy to see you've got it figured it out but still wanted to recommend upgrading 😅 If you happen to upgrade your Refine dependencies to the latest and the issue still continues, please let us know 🙏
stormy-gold
stormy-gold6mo ago
Thanks @aliemirs . I migrated just this pass weekend and did notice and used the key prop for Authenticated. But I saw the issue even going straight to the useIsAuthenticated hook (not using the <Authenticated/> component. I suspect (but have not verified) that it has to do with the fact that the top level Route is rendering the <Authenticated /> component, so perhaps nesting Autneticated within Authenticated is problematic? Regardless, i much prefer relying on that top-level Authenticated component. Much nicer solution. Thanks.
correct-apricot
correct-apricot4mo ago
@Jorge Hey, does your <Authenticated/> component work when changing resources in the browser? When my access token expires and I navigate from let's /users to /events the <Authenticated/> doesn't trigger check() method for me. Does this work for you?