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

React useContext报错:login is not a function问题求助

排查Uncaught (in promise) TypeError: login is not a function错误

1. 核对AuthContext的实现逻辑

首先确认AuthContext的创建与Provider值的正确性:

  • TypeScript类型校验:确保Context的类型定义包含login函数,且初始值符合类型要求(避免初始值为{}这类不完整对象)。示例正确写法:
    import { createContext, useContext, useState } from 'react';
    
    interface AuthContextType {
      user: User | null;
      login: (credentials: Credentials) => Promise<void>;
    }
    
    // 初始值设为undefined,后续通过useAuth钩子做存在性校验
    const AuthContext = createContext<AuthContextType | undefined>(undefined);
    
    export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
      const [user, setUser] = useState<User | null>(null);
    
      // 确保login函数是完整的异步实现
      const login = async (credentials: Credentials) => {
        const res = await fetch('/api/login', {
          method: 'POST',
          body: JSON.stringify(credentials),
        });
        const data = await res.json();
        setUser(data.user);
      };
    
      // Provider的value必须完整包含user和login
      return (
        <AuthContext.Provider value={{ user, login }}>
          {children}
        </AuthContext.Provider>
      );
    };
    
    // 封装useAuth钩子,强制校验Context存在性
    export const useAuth = () => {
      const context = useContext(AuthContext);
      if (!context) {
        throw new Error('useAuth必须在AuthProvider内部使用');
      }
      return context;
    };
    
  • 检查login函数是否存在拼写错误、未定义或被意外覆盖的情况。

2. 验证Provider的全局包裹范围

确保AuthProvider在项目根级别完整包裹所有需要使用登录功能的页面:

  • Pages Router:在_app.tsx中包裹根组件:
    import { AuthProvider } from '../contexts/AuthContext';
    import type { AppProps } from 'next/app';
    
    export default function App({ Component, pageProps }: AppProps) {
      return (
        <AuthProvider>
          <Component {...pageProps} />
        </AuthProvider>
      );
    }
    
  • App Router(Next.js 13+):在app/layout.tsx中包裹根布局:
    import { AuthProvider } from '@/contexts/AuthContext';
    
    export default function RootLayout({
      children,
    }: {
      children: React.ReactNode;
    }) {
      return (
        <html lang="en">
          <body>
            <AuthProvider>{children}</AuthProvider>
          </body>
        </html>
      );
    }
    

若Provider仅包裹部分组件,登录页面可能不在Context生效范围内,导致login未定义。

3. 检查登录页面的Context调用方式

确保登录页面使用封装好的useAuth钩子,而非直接调用useContext:

import { useAuth } from '../contexts/AuthContext';

export default function LoginPage() {
  const { login } = useAuth();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    // 可临时添加日志验证login是否为函数
    console.log('login函数:', typeof login);
    try {
      await login({ email: 'test@example.com', password: '123456' });
    } catch (err) {
      console.error(err);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* 表单内容 */}
    </form>
  );
}

直接使用useContext(AuthContext)且未做存在性校验时,可能拿到初始的undefined,解构后login为undefined。

4. 排查依赖版本兼容性

  • 确认React、Next.js版本无冲突,避免因版本差异导致Context传递异常。
  • 若使用Next.js 13+ App Router,需注意Server Components与Client Components的区分:AuthContext相关代码需放在Client Component中(添加'use client'指令)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:52:13