clerk-react-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

React SPA Patterns

React SPA 模式

This skill covers
@clerk/react
for Vite/CRA SPAs. For Next.js use
clerk-nextjs-patterns
. For TanStack Start use
clerk-tanstack-patterns
.
本技能介绍适用于Vite/CRA单页应用的
@clerk/react
使用方法。Next.js场景请使用
clerk-nextjs-patterns
,TanStack Start场景请使用
clerk-tanstack-patterns

What Do You Need?

所需内容

TaskReference
useAuth / useUser / useClerk hooksreferences/hooks.md
Protected routes with React Routerreferences/protected-routes.md
Custom sign-in / sign-up formsreferences/custom-flows.md
React Router v6/v7 integrationreferences/router-integration.md
任务参考文档
useAuth / useUser / useClerk 钩子references/hooks.md
基于React Router的受保护路由references/protected-routes.md
自定义登录/注册表单references/custom-flows.md
React Router v6/v7 集成references/router-integration.md

References

参考文档

ReferenceDescription
references/hooks.md
useAuth, isLoaded guard
references/protected-routes.md
ProtectedRoute pattern
references/custom-flows.md
useSignIn, useSignUp flows
references/router-integration.md
React Router v6/v7 setup
文档路径描述
references/hooks.md
useAuth、isLoaded守卫
references/protected-routes.md
ProtectedRoute 模式
references/custom-flows.md
useSignIn、useSignUp 流程
references/router-integration.md
React Router v6/v7 配置

Setup

安装配置

npm install @clerk/react
.env
:
VITE_CLERK_PUBLISHABLE_KEY=pk_...
src/main.tsx
:
tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { ClerkProvider } from '@clerk/react'
import App from './App.tsx'

const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ClerkProvider publishableKey={PUBLISHABLE_KEY}>
      <App />
    </ClerkProvider>
  </StrictMode>,
)
npm install @clerk/react
.env
配置:
VITE_CLERK_PUBLISHABLE_KEY=pk_...
src/main.tsx
:
tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { ClerkProvider } from '@clerk/react'
import App from './App.tsx'

const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ClerkProvider publishableKey={PUBLISHABLE_KEY}>
      <App />
    </ClerkProvider>
  </StrictMode>,
)

Mental Model

心智模型

@clerk/react
is client-only — there is no server-side
auth()
. All auth state comes from hooks.
  • isLoaded
    must be
    true
    before trusting
    isSignedIn
    — always guard on
    isLoaded
  • useClerk()
    gives access to
    signOut
    ,
    openSignIn
    ,
    openUserProfile
    and other methods
  • getToken()
    from
    useAuth()
    fetches the session JWT for API calls
@clerk/react
是纯客户端库,不存在服务端
auth()
方法,所有身份验证状态都来自钩子。
  • 在信任
    isSignedIn
    取值前必须确保
    isLoaded
    true
    ——始终要先做
    isLoaded
    校验
  • useClerk()
    可访问
    signOut
    openSignIn
    openUserProfile
    等方法
  • useAuth()
    提供的
    getToken()
    可获取会话JWT用于API调用

Minimal Pattern

最简示例

tsx
import { useAuth } from '@clerk/react'

export function Dashboard() {
  const { isLoaded, isSignedIn, userId } = useAuth()

  if (!isLoaded) return <div>Loading...</div>
  if (!isSignedIn) return <div>Please sign in</div>

  return <div>Hello {userId}</div>
}
tsx
import { useAuth } from '@clerk/react'

export function Dashboard() {
  const { isLoaded, isSignedIn, userId } = useAuth()

  if (!isLoaded) return <div>Loading...</div>
  if (!isSignedIn) return <div>Please sign in</div>

  return <div>Hello {userId}</div>
}

Protected Route (React Router v6/v7)

受保护路由(React Router v6/v7)

tsx
import { Navigate, Outlet } from 'react-router-dom'
import { useAuth } from '@clerk/react'

export function ProtectedRoute() {
  const { isLoaded, isSignedIn } = useAuth()

  if (!isLoaded) return <div>Loading...</div>
  if (!isSignedIn) return <Navigate to="/sign-in" replace />

  return <Outlet />
}
tsx
<Routes>
  <Route element={<ProtectedRoute />}>
    <Route path="/dashboard" element={<Dashboard />} />
    <Route path="/settings" element={<Settings />} />
  </Route>
  <Route path="/sign-in" element={<SignIn />} />
</Routes>
tsx
import { Navigate, Outlet } from 'react-router-dom'
import { useAuth } from '@clerk/react'

export function ProtectedRoute() {
  const { isLoaded, isSignedIn } = useAuth()

  if (!isLoaded) return <div>Loading...</div>
  if (!isSignedIn) return <Navigate to="/sign-in" replace />

  return <Outlet />
}
tsx
<Routes>
  <Route element={<ProtectedRoute />}>
    <Route path="/dashboard" element={<Dashboard />} />
    <Route path="/settings" element={<Settings />} />
  </Route>
  <Route path="/sign-in" element={<SignIn />} />
</Routes>

Token for API Calls

API调用令牌获取

tsx
import { useAuth } from '@clerk/react'

export function DataFetcher() {
  const { getToken } = useAuth()

  async function fetchData() {
    const token = await getToken()
    if (!token) return

    const res = await fetch('/api/data', {
      headers: { Authorization: `Bearer ${token}` },
    })
    return res.json()
  }

  return <button onClick={fetchData}>Load</button>
}
tsx
import { useAuth } from '@clerk/react'

export function DataFetcher() {
  const { getToken } = useAuth()

  async function fetchData() {
    const token = await getToken()
    if (!token) return

    const res = await fetch('/api/data', {
      headers: { Authorization: `Bearer ${token}` },
    })
    return res.json()
  }

  return <button onClick={fetchData}>Load</button>
}

Common Pitfalls

常见陷阱

SymptomCauseFix
isSignedIn
is
undefined
isLoaded
is still
false
Always check
isLoaded
first
ClerkProvider
missing
Provider not at rootWrap
<App>
in
main.tsx
Env var undefinedWrong Vite prefixUse
VITE_CLERK_PUBLISHABLE_KEY
, access via
import.meta.env
Token is
null
User not signed inNull-check
getToken()
result
Sign-in component shows blankNo
publishableKey
on provider
Pass
publishableKey
explicitly
现象原因解决方案
isSignedIn
取值为
undefined
isLoaded
仍为
false
始终优先校验
isLoaded
状态
提示
ClerkProvider
缺失
根组件未包裹Provider
main.tsx
中用
ClerkProvider
包裹
<App>
组件
环境变量未定义Vite环境变量前缀错误使用
VITE_CLERK_PUBLISHABLE_KEY
命名,通过
import.meta.env
访问
Token返回
null
用户未登录
getToken()
返回结果做空值校验
登录组件显示空白Provider未传入
publishableKey
显式传入
publishableKey
参数

See Also

相关内容

  • clerk-setup
    - Initial Clerk install
  • clerk-custom-ui
    - Custom flows & appearance
  • clerk-orgs
    - B2B organizations
  • clerk-setup
    - Clerk初始安装
  • clerk-custom-ui
    - 自定义流程与外观
  • clerk-orgs
    - B2B组织管理

Docs

文档