使用RTK Query如何无需调用服务器存储授权Token至状态?
解决RTK Query初始化存入Token到状态的问题
方案一:通过自定义Action更新API切片状态
RTK Query的createApi支持添加自定义reducer,用来处理非API请求的状态更新,刚好满足你无需调用API就存入Token的需求:
- 在apiSlice中定义自定义reducer与action
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // 你已经实现的Cookie读取函数 const getTokenFromCookie = () => { // 替换成你的Cookie解析逻辑 return document.cookie.split('; ').find(row => row.startsWith('token='))?.split('=')[1]; }; export const apiSlice = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl: '/api', // 从apiSlice状态中获取Token并设置请求头 prepareHeaders: (headers, { getState }) => { const token = getState().api.authToken; if (token) { headers.set('Authorization', `Bearer ${token}`); } return headers; }, }), endpoints: (builder) => ({ // 你的API接口定义 }), // 添加自定义reducer处理Token存入 reducers: { setAuthToken: (state, action) => { state.authToken = action.payload; }, }, }); // 导出自定义action供外部调用 export const { setAuthToken } = apiSlice.actions;
- 应用启动时dispatch该action
在应用入口文件(如index.js/App.js)中,拿到Cookie里的Token后直接触发状态更新:
import { Provider } from 'react-redux'; import { store } from './app/store'; import { setAuthToken } from './features/api/apiSlice'; import { getTokenFromCookie } from './utils/cookieUtils'; // 初始化时存入Token const initialToken = getTokenFromCookie(); if (initialToken) { store.dispatch(setAuthToken(initialToken)); } ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
方案二:单独创建Auth切片(状态分离更清晰)
如果希望授权状态与API切片解耦,可单独创建authSlice:
- 创建authSlice
import { createSlice } from '@reduxjs/toolkit'; const authSlice = createSlice({ name: 'auth', initialState: { token: null }, reducers: { setToken: (state, action) => { state.token = action.payload; }, }, }); export const { setToken } = authSlice.actions; export default authSlice.reducer;
- 在store中注册该切片
import { configureStore } from '@reduxjs/toolkit'; import { apiSlice } from './features/api/apiSlice'; import authReducer from './features/auth/authSlice'; export const store = configureStore({ reducer: { [apiSlice.reducerPath]: apiSlice.reducer, auth: authReducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(apiSlice.middleware), });
- 在apiSlice中读取auth状态的Token
baseQuery: fetchBaseQuery({ baseUrl: '/api', prepareHeaders: (headers, { getState }) => { const token = getState().auth.token; if (token) { headers.set('Authorization', `Bearer ${token}`); } return headers; }, }),
- 应用启动时dispatch存入Token
和方案一逻辑一致,在入口文件执行:
const initialToken = getTokenFromCookie(); if (initialToken) { store.dispatch(setToken(initialToken)); }
关键说明
- 两种方案都无需调用API,直接通过Redux action完成状态更新,完全匹配你的需求。
- 方案二更适合后续授权逻辑扩展,状态分离更清晰;方案一简洁直接,适合简单场景。
内容的提问来源于stack exchange,提问作者Tsabary
相关产品推荐
相关产品推荐

