React全局Context Hook替换API调用失效,请求技术支持
问题修复方案
核心问题分析
你的代码存在三个关键错误:Context使用方式错误、异步函数未正确处理、错误捕获逻辑不完善,以下是针对性修复:
1. 修正useUser的调用与解构
你在事件处理函数内调用useUser违反了React Hooks规则,且未正确解构Context中的login函数,导致调用失败。
修复代码(组件内)
// 必须在组件顶层调用useUser,解构出login函数 const { login } = useUser(); const handleSubmit = async (e: any) => { e.preventDefault(); setLoading(prev => !prev); setResult(''); console.log('submitted form'); try { // 异步函数必须加await,等待登录请求完成 await login(email, password); setIsloggedin(true); router.replace('/dashboard'); } catch (error) { // 优化错误提示,避免空弹窗 const errorMsg = error?.response?.data?.detail || error?.message || '登录失败,请重试'; alert(errorMsg); } finally { setLoading(prev => !prev); } }
2. 完善Context文件的错误处理与依赖导入
你的Context文件缺少axios导入,且异步函数未抛出错误,导致组件无法捕获请求失败的情况。
修复代码(Context文件)
'use client' import { ID } from "appwrite"; import { createContext, useContext, useEffect, useState } from "react"; import { account } from '../appwrite'; import axios from 'axios'; // 新增axios导入 const UserContext = createContext(); export function UserProvider(props) { const [user, setUser] = useState(null); async function login(email, password) { try { const response = await axios.post('/api/login', {email, password} ); // 通常后端用户数据在response.data中,而非整个response对象 setUser(response.data); return response.data; } catch (err) { // 抛出错误,让组件的catch块能捕获 throw err; } } async function register (email, password, name) { try { const response = await axios.post('/api/signup', { email, password, name} ); return response.data; } catch (err) { throw err; } } async function logout() { try { // 注意:logout接口路径通常为/api/logout,需根据后端调整 await axios.post('/api/logout'); setUser(null); } catch (err) { throw err; } } async function init() { try { const loggedIn = await account.get(); setUser(loggedIn); } catch (err) { setUser(null); } } useEffect(() => { init(); }, []); return ( <UserContext.Provider value={{ current: user, login, logout, register }}> {props.children} </UserContext.Provider> ); } export function useUser() { const context = useContext(UserContext); // 增加调试判断:确保useUser在UserProvider范围内使用 if (!context) { throw new Error('useUser必须在UserProvider组件内使用'); } return context; }
3. 额外注意事项
- 确保所有调用
useUser的组件都被RootLayout中的UserProvider包裹(你的代码已满足); - 检查后端接口路径是否正确,比如
logout接口是否应为/api/logout而非/api/currentuser; - 异步函数必须加
await,否则会跳过请求直接执行页面跳转逻辑。
内容的提问来源于stack exchange,提问作者C A OB1
相关产品推荐
相关产品推荐

