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

React Native中工具函数无法访问Redux Store数据的问题

我来帮你解决这个问题——你遇到的核心问题是直接调用configureStore()拿到的是全新的Store实例,和你App里已经初始化、经过Redux Persist持久化的那个完全不是同一个,所以自然拿不到已保存的令牌数据。下面给你两种可行的解决方案,按推荐程度排序:

方案1:导出已初始化的Store实例(最直接)

这是最简单的解决方式,你需要在创建Store的文件(比如store.js)里,把已经初始化并配置好Redux Persist的Store实例导出,而不是只导出configureStore函数。

1.1 修改store.js

// store.js
import { configureStore } from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
import rootReducer from './reducers';
import rootSaga from './sagas';

// Redux Persist配置
const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  whitelist: ['auth'], // 你要持久化的reducer名称
};

const persistedReducer = persistReducer(persistConfig, rootReducer);
const sagaMiddleware = createSagaMiddleware();

// 初始化并导出真实的Store实例
export const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({ serializableCheck: false }).concat(sagaMiddleware),
});

// 启动Saga
sagaMiddleware.run(rootSaga);

// 导出Persistor(供App入口使用)
export const persistor = persistStore(store);

1.2 在api.js中导入这个Store实例

// api.js
import axios from 'axios';
import { store } from './store'; // 导入已初始化的Store实例

export const setHeader = () => {
  // 直接从真实的Store中获取持久化的auth数据
  const { auth } = store.getState();
  if (auth?.token) {
    // 校验令牌过期逻辑
    const isTokenExpired = checkTokenExpiry(auth.token);
    if (!isTokenExpired) {
      axios.defaults.headers.common['Authorization'] = `Bearer ${auth.token}`;
    } else {
      // 令牌过期,触发登出action
      store.dispatch({ type: 'auth/logout' });
      delete axios.defaults.headers.common['Authorization'];
    }
  } else {
    delete axios.defaults.headers.common['Authorization'];
  }
};

// 辅助函数:校验JWT令牌过期
const checkTokenExpiry = (token) => {
  const decoded = JSON.parse(atob(token.split('.')[1]));
  return Date.now() >= decoded.exp * 1000;
};

这样你就能拿到应用中真实的、经过持久化的Store数据,也能直接调用store.dispatch()触发action。

方案2:使用Axios拦截器结合Store(更优雅)

如果想让请求头的设置更自动化,可以把setHeader的逻辑放到Axios的请求拦截器里,同样导入已初始化的Store实例:

// api.js
import axios from 'axios';
import { store } from './store';

// 创建专属Axios实例
const api = axios.create({
  baseURL: 'https://your-api-domain.com',
});

// 请求拦截器:自动添加/校验令牌
api.interceptors.request.use(
  (config) => {
    const { auth } = store.getState();
    if (auth?.token && !checkTokenExpiry(auth.token)) {
      config.headers.Authorization = `Bearer ${auth.token}`;
    } else {
      store.dispatch({ type: 'auth/logout' });
      delete config.headers.Authorization;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器:处理令牌过期后的自动刷新(可选)
api.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;
    // 401未授权且未重试过,尝试刷新令牌
    if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      const { auth } = store.getState();
      // 调用刷新令牌接口
      const refreshRes = await axios.post('/auth/refresh', {
        refreshToken: auth.refreshToken,
      });
      // 更新Store中的令牌
      store.dispatch({
        type: 'auth/updateToken',
        payload: refreshRes.data,
      });
      // 重新设置请求头并重试
      originalRequest.headers.Authorization = `Bearer ${refreshRes.data.token}`;
      return api(originalRequest);
    }
    return Promise.reject(error);
  }
);

export default api;

关键注意事项

  • 确保App入口文件(比如App.js)使用的是同一个store和persistor:
// App.js
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './store';
import MainScreen from './screens/MainScreen';

export default function App() {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <MainScreen />
      </PersistGate>
    </Provider>
  );
}
  • 绝对不要在api.js中重新调用configureStore(),这会创建一个全新的、未持久化的空Store,导致拿不到数据。

内容的提问来源于stack exchange,提问作者Majid Lotfinia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:59:33