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
相关产品推荐
相关产品推荐

