react-admin 的 useGetIdentity 钩子:获取并展示当前登录用户身份(id / fullName / avatar)的完整指南

发布时间:2026/9/21 14:43:52
react-admin 的 useGetIdentity 钩子:获取并展示当前登录用户身份(id / fullName / avatar)的完整指南 react-admin 的 useGetIdentity 钩子获取并展示当前登录用户身份id / fullName / avatar的完整指南【免费下载链接】react-adminA frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design项目地址: https://gitcode.com/gh_mirrors/re/react-adminuseGetIdentity是 react-admin 中封装authProvider.getIdentity()调用逻辑的自定义 Hook用于在应用任何位置获取当前已登录用户的身份信息用户名、头像等也是顶部导航栏用户菜单UserMenu显示登录者姓名与头像的底层实现。读完本文你将掌握useGetIdentity的返回值结构、底层 react-query 工作机制、在页面/表单中的典型实战用法以及如何通过refetch在用户修改资料后刷新身份数据还能了解其源码级实现细节与测试用例。一、useGetIdentity是什么react-admin 需要调用authProvider.getIdentity()来获取并展示当前登录用户的用户名和头像。这个调用逻辑被打包成一个自定义 Hook即useGetIdentity你可以在自己的代码中直接使用它而不必手动触碰 authProvider。它位于ra-core包中源码在 packages/ra-core/src/auth/useGetIdentity.ts同时从 packages/ra-core/src/auth/index.ts 导出并通过react-admin包统一对外暴露import { useGetIdentity } from react-admin或from ra-core。在 react-admin 的应用布局中默认的 UserMenu 组件就内部调用了useGetIdentity()并用identity?.fullName在 AppBar 上渲染用户名见packages/ra-ui-materialui/src/layout/UserMenu.tsx第 75 行与第 96-99 行的条件渲染逻辑。也就是说即使你不直接使用该 Hook它在应用中的首次调用也几乎总是由用户菜单触发。二、基本语法与返回值useGetIdentity()会在组件挂载时调用authProvider.getIdentity()并返回一个包含加载状态、错误状态与身份数据的对象const { data, isPending, error } useGetIdentity();当数据加载完成后data对象包含以下属性const { id, fullName, avatar } data;id用户的唯一标识符必填。fullName用户名/显示名可选。avatar头像 URL可选。这三项在 UserIdentity 接口中定义export interface UserIdentity { id: Identifier; fullName?: string; avatar?: string; [key: string]: any; }值得注意的是该接口带有索引签名[key: string]: any这意味着你的getIdentity可以返回任意自定义字段例如email、roles等react-admin 会原样透传。对应的 authProvider 方法签名见 packages/ra-core/src/types.ts为getIdentity?: (params?: QueryFunctionContext) PromiseUserIdentity;除了解构data外useGetIdentity还额外返回一个别名属性identity即identity与data指向同一个身份对象见源码第 94-100 行的useMemo展开因此你也可以这样写const { identity, isPending, error, refetch } useGetIdentity();三、底层实现基于 react-query 的 useQueryuseGetIdentity使用 react-query 的useQueryHook 来调用 authProvider这一点从源码packages/ra-core/src/auth/useGetIdentity.ts可以清楚看到const result useQuery({ queryKey: [auth, getIdentity], queryFn: async ({ signal }) { if ( authProvider typeof authProvider.getIdentity function ) { return authProvider.getIdentity({ signal }); } else { return defaultIdentity; } }, ...queryOptions, });三个关键实现细节值得展开固定的查询键查询键固定为[auth, getIdentity]。这意味着在同一 QueryClient 作用域内所有调用useGetIdentity的组件共享同一份缓存数据——这正是 UserMenu、页面组件等多处调用不会重复请求的底层原因。同时测试用例 useGetIdentity.spec.tsx 通过queryClient.cancelQueries({ queryKey: [auth, getIdentity] })来取消查询并验证signal的abort事件被触发说明查询取消能力对getIdentity同样生效。AbortSignal 透传queryFn收到 react-query 提供的signal参数并把它传给authProvider.getIdentity({ signal })。如果查询被取消例如组件卸载或手动取消signal会触发abort允许 authProvider 中断正在进行的网络请求避免资源浪费。缺省回退如果当前没有注册 authProvider或 authProvider 未实现getIdentity方法useGetIdentity不会抛错而是返回默认身份defaultIdentity { id: }见源码第 12-14 行。对应测试 should not throw errors when there is no authProvider.getIdentityuseGetIdentity.spec.tsx验证了这一点渲染结果既不显示 Loading 也不显示 Error而是输出{id:}。默认配置Hook 的默认staleTime为 5 分钟staleTime: 5 * 60 * 1000见源码第 15-17 行即身份数据在 5 分钟内被视为新鲜重复挂载组件不会触发重新请求。你可以通过传入选项覆盖它const { data, isPending, error } useGetIdentity({ staleTime: 60 * 1000, // 1 分钟内不重新请求 retry: false, // 失败不重试 onSuccess: (identity) { /* 数据就绪回调 */ }, onError: (err) { /* 出错回调 */ }, onSettled: (data, error) { /* 无论成败都会回调 */ }, });其中onSuccess、onError、onSettled是UseGetIdentityOptions见 useGetIdentity.ts提供的扩展回调内部通过useEvent包装以保证回调引用稳定并在数据就绪/出错/settled 时通过useEffect触发源码第 73-92 行。四、实战用法根据当前用户身份控制 UI一个典型的场景是当某条记录被其他用户锁定编辑时当前用户应看到只读的 Show 页面而非 Edit 页面。下面的PostDetail组件同时使用useGetOne获取记录、useGetIdentity获取当前用户比较post.lockedBy与identity.id来决定渲染哪个视图import { useGetIdentity, useGetOne } from ra-core; const PostDetail ({ id }) { const { data: post, isPending: isPendingPost } useGetOne(posts, { id }); const { data: identity, isPending: isPendingIdentity } useGetIdentity(); if (isPendingPost || isPendingIdentity) return Loading.../; if (!post.lockedBy || post.lockedBy identity.id) { // post isnt locked, or is locked by me return PostEdit post{post} / } else { // post is locked by someone else and cannot be edited return PostShow post{post} / } }两个数据请求并行发出必须同时等待加载完成再做出分支判断否则identity可能为undefined导致运行时错误。这正是useGetIdentity返回isPending状态的典型用法。这个场景在 Storybook 示例 useGetIdentity.stories.tsx 中也有对应的Basic演示其 mock authProvider 返回{ id: 1, fullName: John Doe }组件渲染后展示John Doe测试用例 should return the identityuseGetIdentity.spec.tsx通过screen.findByText(John Doe)断言了该行为。五、刷新身份修改用户名/头像后调用 refetch如果你的应用包含一个让当前用户更新姓名或头像的表单提交后需要刷新身份数据。由于useGetIdentity基于 react-query 的useQuery你可以直接利用其返回的refetch函数强制重新调用authProvider.getIdentity()并通知所有订阅了该查询的组件——包括 AppBar 里的 UserMenu——同步更新展示const IdentityForm () { const { isPending, error, data, refetch } useGetIdentity(); const [newIdentity, setNewIdentity] useState(); if (isPending) return Loading/; if (error) return Error/; const handleChange event { setNewIdentity(event.target.value); }; const handleSubmit (e) { e.preventDefault(); if (!newIdentity) return; fetch(/update_identity, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ identity: newIdentity }) }).then(() { // call authProvider.getIdentity() again and notify the listeners of the result, // including the UserMenu in the AppBar refetch(); }); }; return ( form onSubmit{handleSubmit} input defaultValue{data.fullName} onChange{handleChange} / input typesubmit valueSave / /form ); };这段代码的要点表单先通过fetch将新身份提交到后端持久化提交成功后调用refetch()重新执行getIdentity()由于查询键[auth, getIdentity]是共享的refetch会同时触发所有使用该查询键的组件更新源码注释明确提到 including the UserMenu in the AppBar。上述流程在 Storybook 的ResetIdentity示例useGetIdentity.stories.tsx和测试 should allow to update the identity after a changeuseGetIdentity.spec.tsx中均有完整验证输入框初始值为John Doe改为Jane Doe并点击 Save 后界面更新为Jane Doe。六、错误处理与注意事项错误状态当authProvider.getIdentity()返回被拒绝的 Promise 时useGetIdentity会把错误放入error字段isPending变为false。你可以据此渲染错误 UIconst { identity, isPending, error } useGetIdentity(); if (isPending) return Spinner /; if (error) return ErrorPage error{error} /; return Welcome user{identity} /;Storybook 的ErrorCaseuseGetIdentity.stories.tsx演示了getIdentity返回Promise.reject(new Error(Error))时的表现测试 should return the authProvider erroruseGetIdentity.spec.tsx断言此时渲染出 Error。注意该示例在测试中通过QueryClient的defaultOptions.queries.retry: false关闭了重试避免测试长时间等待。注意事项汇总未实现 getIdentity 时不会报错无 authProvider 或未实现getIdentity时返回{ id: }请确保代码对identity.id为空串的情况有合理处理。缓存与陈旧时间默认 5 分钟staleTime跨组件共享缓存需要实时身份数据时请调整staleTime或显式调用refetch。加载态必须处理isPending为true时data/identity为undefined在解构使用前务必先做加载态判断如第四节示例所示。取消支持getIdentity会收到 AbortSignalauthProvider 内部应监听signal以支持请求取消。七、相关资源本文核心 API 说明两个版本的官方文档docs_headless/src/content/docs/useGetIdentity.md 与 docs/useGetIdentity.md源码实现packages/ra-core/src/auth/useGetIdentity.ts身份类型定义packages/ra-core/src/types.ts单元测试packages/ra-core/src/auth/useGetIdentity.spec.tsxStorybook 示例packages/ra-core/src/auth/useGetIdentity.stories.tsx实际消费方AppBar 用户菜单packages/ra-ui-materialui/src/layout/UserMenu.tsx了解更多 authProvider 的getIdentity契约与完整身份认证体系可参阅 docs/AuthProviderWriting.md 与 docs/Authentication.md【免费下载链接】react-adminA frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design项目地址: https://gitcode.com/gh_mirrors/re/react-admin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考