React中useContext与useRef配合异常:登录后user值为null
问题:登录后Context中的user始终为null
我正在开发一个简单博客应用,使用useContext结合useRef存储用户信息,但登录后执行console.log('user: '+ user)得到的结果是user: null,而非预期的用户对象。
相关代码
Login.jsx
import "./login.css"; import { Link } from "react-router-dom"; import { useContext, useRef } from "react"; import { Context } from "../../../context/Context"; import axios from "axios"; export default function Login() { const userRef = useRef(); const passwordRef = useRef(); const { user, dispatch, isFetching } = useContext(Context); const handleSubmit = async (e) => { e.preventDefault(); dispatch({ type: "LOGIN_START" }); try { const res = await axios.post("/auth/login", { username: userRef.current, password: passwordRef.current, }); dispatch({ type: "LOGIN_SUCCESS", payload: res.data }); } catch (err) { dispatch({ type: "LOGIN_FAILURE" }); } }; console.log('user: '+ user) return ( <div className="login"> <span className="login--title">Login</span> <form className="login--form" onSubmit={handleSubmit}> <label>Username</label> <input type="text" className="login--input" placeholder="Enter your username..." ref={userRef} /> <label>Password</label> <input type="password" className="login--input" placeholder="Enter your password..." ref={passwordRef} /> <button className="login--btn" type="submit"> Login </button> </form> <button className="login--register-btn"> <Link className="link" to="/register"> Register </Link> </button> </div> ); }
Context.js
import { createContext, useReducer } from "react"; import Reducer from "./Reducer"; const INITIAL_STATE = { user: null, isFetching: false, error: false, }; export const Context = createContext(INITIAL_STATE); export const ContextProvider = ({ children }) => { const [state, dispatch] = useReducer(Reducer, INITIAL_STATE); return ( <Context.Provider value={{ user: state.user, isFetching: state.isFetching, error: state.error, dispatch, }} > {children} </Context.Provider> ); };
Reducer.js
const Reducer = (state, action) => { switch (action.type) { case "LOGIN_START": return { user: null, isFetching: true, error: false, }; case "LOGIN_SUCCESS": return { user: action.payload, isFetching: false, error: false, }; case "LOGIN_FAILURE": return { user: null, isFetching: false, error: true, }; case "UPDATE_START": return { ...state, isFetching: true, }; case "UPDATE_SUCCESS": return { user: action.payload, isFetching: false, error: false, }; case "UPDATE_FAILURE": return { user: state.user, isFetching: false, error: true, }; case "LOGOUT": return { user: null, isFetching: false, error: false, }; default: return state; } }; export default Reducer;
问题原因及解决方案
1. 核心错误:useRef获取输入值的方式错误
你当前直接传递userRef.current和passwordRef.current给后端,这两个值是DOM元素对象,不是输入框的文本值。后端无法识别这样的参数,会导致登录请求失败,最终走到LOGIN_FAILURE分支,user保持为null。
修正方式:获取输入框的value属性:
const res = await axios.post("/auth/login", { username: userRef.current.value, password: passwordRef.current.value, });
2. 优化日志打印,确保看到更新后的user
当前console.log写在组件顶层,只会在组件初始化和每次渲染时执行。如果要观察登录后的user变化,建议用useEffect监听user的变化:
import { useEffect } from "react"; // ... 其他代码 useEffect(() => { console.log('user:', user); }, [user]); // 只有当user变化时才打印
3. 排查后端请求错误(可选)
如果修正后还是有问题,可以在catch块中打印错误信息,确认后端返回的具体问题:
catch (err) { console.error('登录请求错误:', err.response?.data || err.message); dispatch({ type: "LOGIN_FAILURE" }); }
内容的提问来源于stack exchange,提问作者ChronoKross
相关产品推荐
相关产品推荐

