diff --git a/lib/src/authenticate.tsx b/lib/src/authenticate.tsx index 3bf650c0..2981e757 100644 --- a/lib/src/authenticate.tsx +++ b/lib/src/authenticate.tsx @@ -30,6 +30,7 @@ import { import { SPACustomGrantConfig } from "@asgardeo/auth-spa/src/models/request-custom-grant"; import React, { FunctionComponent, + MutableRefObject, PropsWithChildren, ReactNode, createContext, @@ -78,8 +79,6 @@ const AuthProvider: FunctionComponent ({ ...defaultConfig, ...passedConfig }), [ passedConfig ] ); - const isSignInInitiated = useRef(false); - const signIn = async( config?: SignInConfig, authorizationCode?: string, @@ -134,6 +133,7 @@ const AuthProvider: FunctionComponent AuthClient.trySignInSilently(state, dispatch); const [ error, setError ] = useState(); + const reRenderCheckRef: MutableRefObject = useRef(false); useEffect(() => { if (state.isAuthenticated) { @@ -149,12 +149,17 @@ const AuthProvider: FunctionComponent { - // Prevent multiple renderings - if (isSignInInitiated.current) { + // React 18.x Strict.Mode has a new check for `Ensuring reusable state` to facilitate an upcoming react feature. + // https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state + // This will remount all the useEffects to ensure that there are no unexpected side effects. + // When react remounts the signIn hook of the AuthProvider, it will cause a race condition. Hence, we have to + // prevent the re-render of this hook as suggested in the following discussion. + // https://github.com/reactwg/react-18/discussions/18#discussioncomment-795623 + if (reRenderCheckRef.current) { return; } - isSignInInitiated.current = true; + reRenderCheckRef.current = true; (async () => { let isSignedOut: boolean = false;