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

Next.js自定义UserType获取用户信息报错问题求助

问题描述

我定义了UserType类型和getUser函数,希望不用在客户端组件里直接调用useSession()就能获取用户信息,但调用时要么返回undefined(访问属性时)要么返回空对象(访问整体时)。调整代码后又触发「Invalid hook call」错误,最终想要拿到包含name、email、base64格式头像的用户对象。

原类型定义代码

"use client"
import { useSession } from "next-auth/react"

interface UserType {
  name: string,
  email: string,
  imageProfile: string,
}

const getUser = (): UserType => {
  const { data: session } = useSession()
  if (session) {
    return {
      name: session.user["name"],
      email: session.user["email"],
      imageProfile: session.user["jpegPhoto"]
    }
  }
  return null
};

export { getUser }

调用组件代码

import { getUser } from "../../../@types/UserType";
import { ClientImage } from "../../../components/ClientImage";
import DevComponent from "../../../components/DevComponents";

export default function Profile() {
  const user = getUser
  console.log("usuario:", user)
  return (
    <div>
      <h1>Profile Page</h1>
      <ClientImage />
      <DevComponent />
    </div>
  );
};

尝试过的操作

  • 调用方式调整:
    const user = getUser()
    console.log("usuario:", user.name)
    
    const user = getUser
    console.log("usuario:", user)
    
  • 修改类型组件代码:
    "use client"
    import { useSession } from "next-auth/react"
    
    interface UserType {
      name: string,
      email: string,
      imageProfile: string,
    }
    
    const getUser = ({name,email, imageProfile}: UserType) => {
      const { data: session } = useSession()
      if (session) {
        return {
          name: session?.user["name"],
          email: session?.user["email"],
          imageProfile: session?.user["jpegPhoto"]
        }
      }
      return null
    };
    
    export { getUser }
    

调整后出现的错误

Unhandled Runtime Error
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

Source
src/types/UserType.ts (11:38) @ useSession

   9 |
  10 | function getUser(): UserType | null {
> 11 | const { data: session } = useSession()
     |                                    ^
  12 | if (session) {
  13 |   return {
  14 |     name: session?.user["name"] || '',
解决方案

核心问题是React Hook的调用规则:useSession是Hook,必须直接在函数组件的顶层或者自定义Hook内部调用,不能在普通函数里调用。需要把getUser改成自定义Hook,而非普通函数。

修正后的自定义Hook代码

"use client"
import { useSession } from "next-auth/react"

interface UserType {
  name: string;
  email: string;
  imageProfile: string;
}

// 自定义Hook必须以use开头,符合React Hook规则
export const useGetUser = (): UserType | null => {
  const { data: session } = useSession()
  
  if (session?.user) {
    return {
      name: session.user.name ?? '',
      email: session.user.email ?? '',
      imageProfile: session.user.jpegPhoto ?? ''
    }
  }
  
  // 未登录或session不存在时返回null,也可根据需求返回默认值
  return null
};

客户端组件中的正确调用方式

"use client" // 组件需标记为客户端组件,因内部使用客户端Hook
import { useGetUser } from "../../../@types/UserType";
import { ClientImage } from "../../../components/ClientImage";
import DevComponent from "../../../components/DevComponents";

export default function Profile() {
  // 在组件顶层直接调用自定义Hook
  const user = useGetUser()
  
  console.log("usuario:", user)
  
  return (
    <div>
      <h1>Profile Page</h1>
      {user ? (
        <div>
          <p>姓名: {user.name}</p>
          <p>邮箱: {user.email}</p>
          <img src={`data:image/jpeg;base64,${user.imageProfile}`} alt="用户头像" />
        </div>
      ) : (
        <p>未登录</p>
      )}
      <ClientImage />
      <DevComponent />
    </div>
  );
};

关键说明

  1. 自定义Hook命名规则:必须以use开头,React才能识别并确保遵循Hook调用规则。
  2. "use client"指令:自定义Hook内部依赖useSession(客户端Hook),因此调用该Hook的组件必须标记为客户端组件,或Hook文件本身已标记。
  3. 空值处理:用??运算符处理可能的空值,避免访问undefined属性报错。
  4. 调用时机:必须在函数组件的顶层调用自定义Hook,不能在条件判断、循环或嵌套函数内调用。

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:15:05