From aaea49d5f5cd6659b69784fae83769818caf47ef Mon Sep 17 00:00:00 2001 From: Antoine Moreaux Date: Fri, 7 Feb 2025 10:27:11 +0100 Subject: [PATCH] fix(auth): prevent infinite redirect (#10065) Refactored the isMatchingLocation function to use useCallback for memoization, improving performance by avoiding unnecessary re-creations. Moved addTrailingSlash and getConstructedPath inside useCallback for better encapsulation. --- .../src/hooks/useIsMatchingLocation.ts | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/twenty-front/src/hooks/useIsMatchingLocation.ts b/packages/twenty-front/src/hooks/useIsMatchingLocation.ts index da23ae39b..36f525f1f 100644 --- a/packages/twenty-front/src/hooks/useIsMatchingLocation.ts +++ b/packages/twenty-front/src/hooks/useIsMatchingLocation.ts @@ -3,28 +3,36 @@ import { matchPath, useLocation } from 'react-router-dom'; import { AppBasePath } from '@/types/AppBasePath'; import { isNonEmptyString } from '@sniptt/guards'; import { isDefined } from 'twenty-shared'; +import { useCallback } from 'react'; export const useIsMatchingLocation = () => { const location = useLocation(); - const addTrailingSlash = (path: string) => - path.endsWith('/') ? path : path + '/'; + // Infinite loop issue caused by `checkUserExistsQuery` in `useSignInUp`. + // Without executing this query, there is no infinite loop. + // I also noticed that in `isMatchingLocation` inside `continueWithEmail`, no loop occurs. + // Both functions are called within the `useEffect` of `SignInUpWorkspaceScopeFormEffect`. + // This led me to conclude that the issue comes from `useIsMatchingLocation`. + // Using `useCallback` prevent the loop. + const isMatchingLocation = useCallback( + (path: string, basePath?: AppBasePath) => { + const addTrailingSlash = (path: string) => + path.endsWith('/') ? path : path + '/'; - const getConstructedPath = (path: string, basePath?: AppBasePath) => { - if (!isNonEmptyString(basePath)) return path; + const getConstructedPath = (path: string, basePath?: AppBasePath) => { + if (!isNonEmptyString(basePath)) return path; - return addTrailingSlash(basePath) + path; - }; + return addTrailingSlash(basePath) + path; + }; - const isMatchingLocation = (path: string, basePath?: AppBasePath) => { - const match = matchPath( - getConstructedPath(path, basePath), - location.pathname, - ); - const isMatching = isDefined(match); - - return isMatching; - }; + const match = matchPath( + getConstructedPath(path, basePath), + location.pathname, + ); + return isDefined(match); + }, + [location.pathname], + ); return { isMatchingLocation,