diff --git a/packages/rn-sample/App.tsx b/packages/rn-sample/App.tsx index f689f89..79a94b9 100644 --- a/packages/rn-sample/App.tsx +++ b/packages/rn-sample/App.tsx @@ -9,7 +9,7 @@ const endpoint = 'https://'; const appId = ''; const Content = () => { - const { signIn, signOut, client, isAuthenticated, getIdTokenClaims } = useLogto(); + const { signIn, signOut, client, isAuthenticated, isInitialized, getIdTokenClaims } = useLogto(); const [claims, setClaims] = useState(); useEffect(() => { @@ -17,10 +17,10 @@ const Content = () => { setClaims(await getIdTokenClaims()); }; - if (isAuthenticated) { + if (isInitialized && isAuthenticated) { void get(); } - }, [isAuthenticated, getIdTokenClaims]); + }, [isAuthenticated, getIdTokenClaims, isInitialized]); return ( diff --git a/packages/rn/package.json b/packages/rn/package.json index 987fd4a..f4e09bc 100644 --- a/packages/rn/package.json +++ b/packages/rn/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "0.2.0", + "version": "0.3.0", "type": "module", "main": "./lib/index.js", "types": "./lib/index.d.ts", diff --git a/packages/rn/src/context.ts b/packages/rn/src/context.ts index a146ea9..13bc39c 100644 --- a/packages/rn/src/context.ts +++ b/packages/rn/src/context.ts @@ -4,6 +4,13 @@ import type { LogtoClient } from './client'; export type LogtoContextProps = { client: LogtoClient; + /** + * Indicates if the client is initialized. + * + * - `true`: The client is initialized, and the authentication state is fetched. + * - `false`: The client is not initialized. + */ + isInitialized: boolean; isAuthenticated: boolean; setIsAuthenticated: React.Dispatch>; }; @@ -15,6 +22,7 @@ export const throwContextError = (): never => { export const LogtoContext = createContext({ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion client: undefined!, + isInitialized: false, isAuthenticated: false, setIsAuthenticated: throwContextError, }); diff --git a/packages/rn/src/hooks.ts b/packages/rn/src/hooks.ts index aad4c0d..7ce958b 100644 --- a/packages/rn/src/hooks.ts +++ b/packages/rn/src/hooks.ts @@ -11,7 +11,7 @@ import { LogtoContext } from './context'; * `LogtoProvider` component to wrap the root component of the app. */ export const useLogto = () => { - const { client, isAuthenticated, setIsAuthenticated } = useContext(LogtoContext); + const { client, isAuthenticated, setIsAuthenticated, isInitialized } = useContext(LogtoContext); useEffect(() => { // This is required to handle the redirect from the browser on a web-based expo app @@ -45,6 +45,10 @@ export const useLogto = () => { * tokens are valid. */ isAuthenticated, + /** + * Indicates if the client is initialized and the authentication state is retrieved from the storage. + */ + isInitialized, /** @see {@link LogtoClient.getRefreshToken} */ getRefreshToken: client.getRefreshToken.bind(client), /** @see {@link LogtoClient.getAccessToken} */ @@ -66,7 +70,7 @@ export const useLogto = () => { /** @see {@link LogtoClient.fetchUserInfo} */ fetchUserInfo: client.fetchUserInfo.bind(client), }), - [client, isAuthenticated, signIn, signOut] + [client, isAuthenticated, isInitialized, signIn, signOut] ); return memorized; diff --git a/packages/rn/src/provider.tsx b/packages/rn/src/provider.tsx index d324648..5c12f71 100644 --- a/packages/rn/src/provider.tsx +++ b/packages/rn/src/provider.tsx @@ -16,12 +16,15 @@ export type LogtoProviderProps = { export const LogtoProvider = ({ config, children }: LogtoProviderProps) => { const memorizedLogtoClient = useMemo(() => new LogtoClient(config), [config]); const [isAuthenticated, setIsAuthenticated] = useState(false); + const [isInitialized, setIsInitialized] = useState(false); useEffect(() => { (async () => { const isAuthenticated = await memorizedLogtoClient.isAuthenticated(); - setIsAuthenticated(isAuthenticated); + + // Mark the client as initialized. + setIsInitialized(true); })(); }, [memorizedLogtoClient]); @@ -29,9 +32,10 @@ export const LogtoProvider = ({ config, children }: LogtoProviderProps) => { () => ({ client: memorizedLogtoClient, isAuthenticated, + isInitialized, setIsAuthenticated, }), - [memorizedLogtoClient, isAuthenticated] + [memorizedLogtoClient, isAuthenticated, isInitialized] ); return {children};