如何在Redux Toolkit切片的reducer中发起RTK Query GET请求?
关于在Redux内部使用RTK Query发起请求的解决方案
首先得明确:Redux的reducer是纯函数,绝对不能在reducer里发起任何异步请求——不管是用Thunk还是RTK Query都不行。因为reducer的职责是接收action、同步更新状态,不能包含网络请求这类副作用,这是Redux的核心规则。
你的需求是在非React组件/钩子的Redux逻辑里触发RTK Query的请求,正确的做法是用RTK Query提供的可dispatch的action创建器,具体步骤如下:
1. 修正你的postsSlice:移除reducer里的异步逻辑
把原来的getPosts同步action改成Thunk action,或者直接用RTK Query的内置action来触发请求。如果需要把RTK Query的请求结果同步到自己的postsSlice,可以新增一个同步更新状态的action:
import { apiSlice } from './apiSlice'; const initialState = { posts: [], // 其他自定义状态 }; export const postsSlice = createSlice({ name: 'posts', initialState, reducers: { // 同步更新posts状态的action setPosts: (state, action) => { state.posts = action.payload; }, }, }); // 定义Thunk action,用来触发RTK Query的getPosts请求 export const fetchPosts = () => async (dispatch) => { // 用RTK Query的initiate方法创建可dispatch的请求action const queryResult = await dispatch(apiSlice.endpoints.getPosts.initiate()); // 如果请求成功,同步数据到postsSlice(可选,RTK Query本身已缓存数据) if (queryResult.isSuccess) { dispatch(postsSlice.actions.setPosts(queryResult.data)); } }; export const { setPosts } = postsSlice.actions;
2. 在Redux内部触发请求
不管是在另一个Thunk action、Redux middleware里,都可以直接dispatch RTK Query的initiate action:
// 示例:在另一个Thunk里触发getPosts请求 export const someOtherThunk = () => async (dispatch) => { // 触发RTK Query的getPosts请求 await dispatch(apiSlice.endpoints.getPosts.initiate()); // 后续逻辑 console.log('请求已完成'); };
3. 可选:自动同步RTK Query数据到postsSlice
如果希望请求完成后自动把数据同步到自己的slice,可以在apiSlice的endpoint里配置onQueryStarted钩子:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; import { postsSlice } from './postsSlice'; export const apiSlice = createApi({ reducerPath: 'api', baseQuery: fetchBaseQuery({ baseUrl }), endpoints: (builder) => ({ getPosts: builder.query({ query: () => '/posts', // 请求完成后自动同步数据到postsSlice async onQueryStarted(_arg, { dispatch, queryFulfilled }) { try { const { data } = await queryFulfilled; dispatch(postsSlice.actions.setPosts(data)); } catch (err) { // 处理请求错误 console.error('获取帖子失败:', err); } }, }), }), }); export const { useGetPostsQuery } = apiSlice;
关键提醒
其实大部分场景下,你不需要单独维护postsSlice——RTK Query已经自动帮你管理了请求状态、缓存、数据更新等逻辑。只有当你需要对数据做额外的自定义状态管理时,才需要同步到自己的slice。
内容的提问来源于stack exchange,提问作者Onyx
相关产品推荐
相关产品推荐

