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

首次页面加载时RTK createApi如何访问localStorage或env中的baseUrl配置

问题根因

你遇到的问题本质是代码执行时机顺序不匹配:

  • src/services/api.ts 中的顶层代码会在模块导入时立刻执行,也就是你的 localStorage.getItem 操作远早于App.tsx中useEffect的执行时机
  • 首次加载时useEffect还没把.env的接口地址写入localStorage,createApi就已经完成初始化,自然读取不到正确值

解决方案

方案1:使用动态baseQuery(最推荐,兼容后续baseUrl变更)

不要在模块顶层固定baseUrl,而是在每次发起请求时动态读取redux store或localStorage中的最新值,RTK Query的baseQuery支持访问store全局状态:

// src/services/api.ts 修改后代码
import { fetchBaseQuery, createApi } from '@reduxjs/toolkit/query/react';

export const dataApis = createApi({
  reducerPath: 'dataApis',
  baseQuery: async (args, api, extraOptions) => {
    // 优先从store取,其次取localStorage,保证拿到的是最新值
    const baseUrl = api.getState().reducerSlice.apiEndpoint || localStorage.getItem(config.apiEndpoint) || '';
    const baseQuery = fetchBaseQuery({ baseUrl });
    return baseQuery(args, api, extraOptions);
  },
  endpoints: (builder) => ({
    // 原有接口定义完全不需要修改
  })
})

这个方案的优势是就算后续运行时baseUrl发生变化,不需要重新初始化api,所有请求自动生效。

方案2:提前配置localStorage时机(改造成本最低,原有api代码无需调整)

把原来写在App.tsx useEffect里的env读取逻辑,提前到应用初始化、store/createApi初始化之前执行,保证api模块初始化时localStorage已经有值:

// src/main.tsx 入口文件修改
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import App from './App';
import { configureStore } from '@reduxjs/toolkit';
import { dataApis } from './services/api';
import { reducerSlice } from './redux/reducerSlice';

// 提前处理.env配置,在初始化store和api前完成localStorage写入
const myCustomEndpoint = window._env_.MYENDPOINT;
if(myCustomEndpoint) {
  localStorage.removeItem('api');
  localStorage.setItem('api', myCustomEndpoint);
}

// 再初始化store和api,此时api.ts顶层读取localStorage已经能拿到正确值
const store = configureStore({
  reducer: {
    [reducerSlice.name]: reducerSlice.reducer,
    [dataApis.reducerPath]: dataApis.reducer,
  },
  middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(dataApis.middleware)
})

// 最后挂载应用
ReactDOM.createRoot(document.getElementById('root')!).render(
  <Provider store={store}>
    <App />
  </Provider>
)

对应的可以删掉App.tsx里原来处理env的useEffect逻辑,避免重复执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:54:03