React Context用户认证登录时报TypeError: setUser is not a function错误
错误原因&修复方案
1. Context导出方法名与调用名不匹配
auth.js中AuthProvider对外暴露的更新方法名为setCurrentUser,但login.js中解构的是setUser,名称不对应导致找不到方法。
2. useAuth调用位置错误
Context的消费钩子useAuth必须在AuthProvider的包裹范围内调用,你在App组件内先调用useAuth再渲染AuthProvider,此时拿到的是createContext的默认空值,所有导出字段都是undefined。
3. setAuth参数处理逻辑错误
你在login.js中调用更新方法时,直接传入了用户对象{username: data.user.username, isAdmin: data.user.isAdmin},但auth.js的setAuth中按data.user.username取值,多了一层user嵌套,后续会触发属性读取错误。
4. 后端返回格式问题(潜在隐患)
Flask路由直接返回字典不会自动添加application/json响应头,部分浏览器会解析失败,最好用jsonify包裹返回值。
修复后代码
auth.js
import { createContext, useContext, useState } from "react"; export const AuthContext = createContext(); export const AuthProvider = function({ children }) { // 初始化从sessionStorage读取用户信息,避免刷新丢失 const initUser = { username: sessionStorage.getItem('username') || null, isAdmin: sessionStorage.getItem('isAdmin') === 'true' } const [currentUser, setCurrentUser] = useState(initUser); const setUser = (user) => { sessionStorage.setItem('username', user.username); sessionStorage.setItem('isAdmin', user.isAdmin); setCurrentUser(user); } return ( <AuthContext.Provider value={{ currentUser, setUser }}> {children} </AuthContext.Provider> ) } export function useAuth() { return useContext(AuthContext); }
App.js
import { BrowserRouter as Router } from "react-router-dom"; import { AuthProvider } from './context/auth'; import "bootstrap/dist/css/bootstrap.min.css"; /* Begin Import Components */ import NavigationBar from "./components/navbar"; import Public from "./components/public-components/public"; /* End Import Components */ function App(props) { return ( <AuthProvider> <Router> <NavigationBar /> <div className="container text-center"> <Public /> </div> </Router> </AuthProvider> ); } export default App;
Flask api.py
from flask import jsonify @app.route("/login", methods=['POST']) def login(): try: email = request.form['email'] password = request.form['password'] user = db.session.query(User.username, User.password).filter_by(email=email).first() # 新增用户不存在判断,避免空指针报错 if not user: return jsonify({'wrongPassword':True}) user_role = db.session.query(UserRole.role).filter_by(username=user.username).first() if(check_password_hash(user.password, password)): if(user_role.role == 'Admin'): return jsonify({'user': {'username': user.username, 'isAdmin': True}}) return jsonify({'user': {'username': user.username, 'isAdmin': False}}) else: return jsonify({'wrongPassword':True}) except Exception as e: print(e) return jsonify({'error':'Something went wrong...'}), 500
login.js无需修改,和现有逻辑完全兼容。
内容的提问来源于stack exchange,提问作者Andrex
相关产品推荐
相关产品推荐

