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

如何修复Cannot read properties of null (reading 'User')报错

问题定位

报错的根本原因是代码直接访问了null值的User属性:

  • 当用户首次访问站点、未完成登录,或者手动清理过浏览器本地存储时,localStorage.getItem("persist:root")会返回null
  • 代码没有对该返回值做非空校验,直接执行.User操作,直接触发类型错误

另外你原有代码还存在一个隐藏问题:axios实例配置的请求头字段是headers,你写的header缺少后缀s,就算拿到了合法token,请求头也不会正常生效。

修复方案

快速修复(解决当前报错)

对每一层取值增加非空校验,用可选链操作符?.和空值合并运算符??兜底异常场景:

import axios from "axios";

const BASE_URL = "http://localhost:5000/api/";
const TOKEN = JSON.parse(
  JSON.parse(
    localStorage.getItem("persist:root") ?? "{}"
  )?.User ?? "{}"
)?.currentUser?.accessToken ?? "";

export const publicRequest = axios.create({
  baseURL: BASE_URL,
});

export const userRequest = axios.create({
  baseURL: BASE_URL,
  headers: { token: `Bearer ${TOKEN}` },
});

优化方案(推荐)

不要在初始化时固定token,改用请求拦截器动态获取最新token,避免用户登录后token更新但请求实例不刷新的问题,同时增加异常捕获避免解析错误:

import axios from "axios";

const BASE_URL = "http://localhost:5000/api/";

export const publicRequest = axios.create({
  baseURL: BASE_URL,
});

export const userRequest = axios.create({
  baseURL: BASE_URL,
});

// 请求拦截器:每次发请求前动态拼接最新token
userRequest.interceptors.request.use(
  (config) => {
    const persistRoot = localStorage.getItem("persist:root");
    if (persistRoot) {
      try {
        const parsedRoot = JSON.parse(persistRoot);
        const userInfo = parsedRoot.User ? JSON.parse(parsedRoot.User) : null;
        const token = userInfo?.currentUser?.accessToken;
        if (token) {
          config.headers.token = `Bearer ${token}`;
        }
      } catch (err) {
        // 解析存储内容失败时清空无效存储,避免后续重复报错
        localStorage.removeItem("persist:root");
      }
    }
    return config;
  },
  (error) => Promise.reject(error)
);

内容的提问来源于stack exchange,提问作者Gregg m

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:06:04