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
相关产品推荐
相关产品推荐

