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

如何将登录用户存入Redux状态?解决TOKEN初始化加载异常

问题解决:MERN+Redux Toolkit持久化后启动API调用提示用户不存在

问题背景

在MERN项目中使用Redux Toolkit存储当前用户信息,通过redux-persist将TOKEN保存在sessionStorage中,但每次启动应用调用需要TOKEN的API时,都会提示“error user is not existed”,核心原因是应用启动时redux-persist尚未完成持久化状态恢复,导致user对象未初始化、TOKEN无法正确获取。

代码问题分析

当前useFetch.js中存在两个关键问题:

  1. 静态TOKEN初始化时机错误:模块加载阶段直接读取sessionStorage,此时redux-persist还未完成状态恢复,sessionStorage.getItem("persist:root")可能返回null,或解析后无currentUser字段,导致TOKEN为undefined。
  2. axios实例请求头固定:userMethod初始化时就固定了请求头,后续Redux状态更新token后,实例不会自动同步最新值。
// 原useFetch.js的问题代码
const TOKEN = (JSON.parse(JSON.parse(sessionStorage.getItem("persist:root")).user).currentUser?.accessToken);

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

解决方案

方案1:用axios请求拦截器动态获取token

修改useFetch.js,通过拦截器在每次请求时从Redux状态动态获取最新token,避免静态初始化的时机问题:

import axios from 'axios';
import store from './store'; // 导入你的Redux store实例

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

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

export const userMethod = axios.create({
    baseURL: BASE_URL
})

// 添加请求拦截器,动态注入token
userMethod.interceptors.request.use(
    (config) => {
        const currentUser = store.getState().user.currentUser;
        if (currentUser) {
            config.headers.token = `Bearer ${currentUser.accessToken}`;
        }
        return config;
    },
    (error) => Promise.reject(error)
)

方案2:等待redux-persist完成状态恢复后渲染应用

在入口文件(如index.js)中使用PersistGate,确保Redux状态完全恢复后再渲染组件、发起API请求:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './store'; // 你的store和persistor实例
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>
);

方案3:登录/登出时手动更新axios实例请求头

在Redux的user切片中,登录成功后更新userMethod的默认请求头,登出时清除,确保token实时同步:

// userRedux.js
import { createSlice } from '@reduxjs/toolkit'
import { userMethod } from '../useFetch';

const userSlice = createSlice({
    name: "user",
    initialState: {
       currentUser: null,
       isFetching: false,
       error: false
    },
    reducers: {
        loginStart: (state) => {
            state.isFetching = true;
        },
        loginSuccess: (state, action) => {
            state.isFetching = false;
            state.currentUser = action.payload;
            // 更新axios实例的默认token
            userMethod.defaults.headers.token = `Bearer ${action.payload.accessToken}`;
        },
        loginFailure: (state) => {
            state.isFetching = false;
            state.error = true;
        },
        logout: (state) => {
            state.currentUser = null;
            // 清除请求头中的token
            delete userMethod.defaults.headers.token;
        }
    }
})

export const { loginStart, loginSuccess, loginFailure, logout } = userSlice.actions
export default userSlice.reducer;

内容的提问来源于stack exchange,提问作者RAHMAN DHIKA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:32:09