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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:50:37