You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:40:05