diff --git a/.changeset/red-cats-approve.md b/.changeset/red-cats-approve.md
new file mode 100644
index 0000000000..2926ba3192
--- /dev/null
+++ b/.changeset/red-cats-approve.md
@@ -0,0 +1,5 @@
+---
+'@clerk/clerk-react': patch
+---
+
+`useAuth` now uses derived auth state instead of locally stored state
diff --git a/packages/react/src/hooks/__tests__/useAuth.test.tsx b/packages/react/src/hooks/__tests__/useAuth.test.tsx
new file mode 100644
index 0000000000..5b78c7c836
--- /dev/null
+++ b/packages/react/src/hooks/__tests__/useAuth.test.tsx
@@ -0,0 +1,24 @@
+import { render } from '@testing-library/react';
+import React from 'react';
+
+import { useAuth } from '../useAuth';
+
+const TestComponent = () => {
+ const { isLoaded, isSignedIn } = useAuth();
+ return (
+
+ {isLoaded}
+ {isSignedIn}
+
+ );
+};
+
+describe('useAuth', () => {
+ test('throws an error if not wrapped in ', () => {
+ expect(() => {
+ render();
+ }).toThrow(
+ '@clerk/clerk-react: useAuth can only be used within the component. Learn more: https://clerk.com/docs/components/clerk-provider',
+ );
+ });
+});
diff --git a/packages/react/src/hooks/__tests__/useAuth.test.ts b/packages/react/src/hooks/__tests__/useAuth.types.test.ts
similarity index 100%
rename from packages/react/src/hooks/__tests__/useAuth.test.ts
rename to packages/react/src/hooks/__tests__/useAuth.types.test.ts
diff --git a/packages/react/src/hooks/useAuth.ts b/packages/react/src/hooks/useAuth.ts
index d666c50d23..bb3a56a4d6 100644
--- a/packages/react/src/hooks/useAuth.ts
+++ b/packages/react/src/hooks/useAuth.ts
@@ -1,6 +1,6 @@
import { createCheckAuthorization } from '@clerk/shared/authorization';
import type { CheckAuthorizationWithCustomPermissions, GetToken, SignOut, UseAuthReturn } from '@clerk/types';
-import { useCallback, useEffect, useState } from 'react';
+import { useCallback } from 'react';
import { useAuthContext } from '../contexts/AuthContext';
import { useIsomorphicClerkContext } from '../contexts/IsomorphicClerkContext';
@@ -50,24 +50,14 @@ type UseAuth = (initialAuthState?: any) => UseAuthReturn;
export const useAuth: UseAuth = (initialAuthState = {}) => {
useAssertWrappedByClerkProvider('useAuth');
- const authContext = useAuthContext();
+ const authContextFromHook = useAuthContext();
+ let authContext = authContextFromHook;
- const [authState, setAuthState] = useState(() => {
- // This indicates the authContext is not available, and so we fallback to the provided initialState
- if (authContext.sessionId === undefined && authContext.userId === undefined) {
- return initialAuthState ?? {};
- }
- return authContext;
- });
-
- useEffect(() => {
- if (authContext.sessionId === undefined && authContext.userId === undefined) {
- return;
- }
- setAuthState(authContext);
- }, [authContext]);
+ if (authContext.sessionId === undefined && authContext.userId === undefined) {
+ authContext = initialAuthState != null ? initialAuthState : {};
+ }
- const { sessionId, userId, actor, orgId, orgRole, orgSlug, orgPermissions, factorVerificationAge } = authState;
+ const { sessionId, userId, actor, orgId, orgRole, orgSlug, orgPermissions, factorVerificationAge } = authContext;
const isomorphicClerk = useIsomorphicClerkContext();
const getToken: GetToken = useCallback(createGetToken(isomorphicClerk), [isomorphicClerk]);