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

React组件外访问Redux状态及添加Reducer遇初始化错误求助

问题

我正在学习Redux,需要配置Axios拦截器,为每个请求设置存储在authSlice中的JWT Token。初始代码可正常运行:

import axios from "axios";
import store from "../global-state/store";

axios.defaults.baseURL = "https://jsonplaceholder.typicode.com";
const state = store.getState();
const token = state.auth.token;

axios.interceptors.request.use(
  (config) => {
    config.headers.Authorization = token ? `token ${token}` : "";
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// Add response interceptor (example: handling common errors)
axios.interceptors.response.use(
  (response) => {
    //  handle successful responses
    return response;
  },
  (error) => {
    // handle errors globally
    if (error.status == 401) {
      window.location.href = "/login";
    }
    if (error.response.status == 403) {
      window.location.href = "/access-denied";
    }

    return Promise.reject(error);
  }
);

export default axios;

但在store中添加counterReducer后,出现以下错误:

store.ts:11 Uncaught ReferenceError: Cannot access 'counterReducer' before initialization
    at store.ts:11:14

对应的store代码:

const store = configureStore({
  reducer: {
    auth: authReducer,
    counter: counterReducer,
  },
});

解决方案

这个错误属于循环依赖+变量初始化顺序问题,具体修复方式如下:

1. 调整store的初始化顺序

在store.ts中,确保所有reducer的导入/定义都在store创建之前:

// 先导入所有reducer
import authReducer from './authSlice';
import counterReducer from './counterSlice';

// 再创建store实例
const store = configureStore({
  reducer: {
    auth: authReducer,
    counter: counterReducer,
  },
});

export default store;

2. 修复Axios拦截器的token获取逻辑

你当前的代码在Axios初始化时就直接读取了store的state,这会导致store未完全初始化就被调用,同时容易引发循环依赖。正确做法是每次请求时动态获取最新的token:

import axios from "axios";
import store from "../global-state/store";

axios.defaults.baseURL = "https://jsonplaceholder.typicode.com";

axios.interceptors.request.use(
  (config) => {
    // 每次请求时实时获取最新的token
    const currentState = store.getState();
    const token = currentState.auth.token;
    config.headers.Authorization = token ? `token ${token}` : "";
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器优化:增加可选链避免报错
axios.interceptors.response.use(
  (response) => {
    return response;
  },
  (error) => {
    if (error.response?.status === 401) {
      window.location.href = "/login";
    }
    if (error.response?.status === 403) {
      window.location.href = "/access-denied";
    }
    return Promise.reject(error);
  }
);

export default axios;

3. 避免异步action中的循环依赖

如果counterSlice的异步action用到了Axios,不要在文件顶部导入,而是在函数内部动态导入:

// counterSlice.js
import { createAsyncThunk } from '@reduxjs/toolkit';

export const fetchCounterData = createAsyncThunk(
  'counter/fetchData',
  async () => {
    // 函数内部动态导入Axios,避免循环依赖
    const axios = await import('../axios');
    const response = await axios.default.get('/some-endpoint');
    return response.data;
  }
);

内容的提问来源于stack exchange,提问作者Quốc Việt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:10:02