Next.js如何将Auth0用户的user.name传入异步请求函数?
问题原因
useUser()是Auth0提供的React客户端Hook,必须严格遵守React Hook调用规则:仅能在客户端组件顶层作用域、自定义Hook内部调用,不能在普通工具函数、服务端执行逻辑、条件判断/循环/嵌套函数中调用。- 你之前将Hook放在非合规位置执行,破坏了Hook的状态执行链路,是应用崩溃的核心原因。
可行实现方案
核心思路是拆分职责:通用请求函数不耦合登录态逻辑,仅接收动态站点名参数完成接口请求;在能合法获取用户信息的上下文(客户端组件/服务端逻辑层)拿到用户名后,传入请求函数即可。
第一步:重构通用请求工具函数
修改utils/wordpress.js,移除硬编码的站点名配置,将站点名作为入参传入:
const WP_DOMAIN = "https://fsm.xristosavgeros.com"; export async function getPosts(siteName) { if (!siteName) throw new Error("站点名参数不能为空"); const requestUrl = `${WP_DOMAIN}/${siteName}/wp-json/wp/v2/work?_embed`; const postsRes = await fetch(requestUrl); if (!postsRes.ok) throw new Error(`WordPress接口请求失败,状态码:${postsRes.status}`); const posts = await postsRes.json(); return posts.filter((post) => post.assigned_to == 'Johnny Worker'); }
第二步:根据渲染模式选择对应方式取数
场景1:客户端组件取数
在客户端组件顶层合法调用useUser,处理完加载/未登录状态后,拿到用户名再触发请求:
// 对应页面文件,必须在顶部加'use client'标记为客户端组件 'use client'; import { useUser } from '@auth0/nextjs-auth0/client'; import { getPosts } from '@/utils/wordpress'; import { useEffect, useState } from 'react'; export default function WorkListPage() { // 必须在组件顶层调用Hook,不要嵌套在其他函数/判断逻辑里 const { user, isLoading, error } = useUser(); const [posts, setPosts] = useState([]); const [postLoading, setPostLoading] = useState(false); useEffect(() => { // 用户态未加载完成时不发请求 if (isLoading || !user?.name) return; const fetchPostData = async () => { setPostLoading(true); try { const data = await getPosts(user.name); setPosts(data); } catch (err) { console.error('文章获取失败', err); } finally { setPostLoading(false); } }; fetchPostData(); }, [user, isLoading]); if (isLoading) return <div>登录状态加载中...</div>; if (error) return <div>登录校验失败:{error.message}</div>; if (!user) return <div>请先登录后查看内容</div>; if (postLoading) return <div>文章列表加载中...</div>; return ( <div className="work-list"> {posts.map(post => ( <div key={post.id}>{post.title.rendered}</div> ))} </div> ); }
场景2:服务端组件/Server Action取数
如果需要首屏服务端渲染、避免客户端暴露请求逻辑,不能使用客户端useUserHook,改用Auth0服务端SDK获取登录会话即可:
// 服务端组件不需要加'use client'标记 import { getSession } from '@auth0/nextjs-auth0'; import { getPosts } from '@/utils/wordpress'; import { redirect } from 'next/navigation'; export default async function WorkListPage() { // 服务端获取当前用户会话 const session = await getSession(); // 未登录直接跳转登录页 if (!session?.user) redirect('/api/auth/login'); // 拿到用户名后直接调用请求函数 const posts = await getPosts(session.user.name); return ( <div className="work-list"> {posts.map(post => ( <div key={post.id}>{post.title.rendered}</div> ))} </div> ); }
注意事项
如果Auth0返回的user.name包含空格、特殊字符、大小写格式和WordPress多站点的路径段规则不匹配,需要提前做一层格式转义/映射,避免接口返回404错误。
内容的提问来源于stack exchange,提问作者avgeros
相关产品推荐
相关产品推荐

