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

如何结合RTK Query与Redux Toolkit实现帖子创建及缓存失效

问题描述

我有一个名为pendingPost的Redux切片,通过reducer函数向其中添加car_mileage等字段,将创建帖子的临时数据保存在该切片中,后续提交时会使用pendingPost切片内的数据:

const pendingPostReducer = createSlice({
  name: 'pendingPost',
  initialState: { savedData: {} },
  reducers: {
    addPropertyToPendingPost: (state, action) => {
      state.savedData = { ...state.savedData, ...action.payload };
    },
    // 后续会用到的清空暂存数据的reducer
    clearPendingPost: (state) => {
      state.savedData = {};
    }
  },
});

export const { addPropertyToPendingPost, clearPendingPost } = pendingPostReducer.actions;
export default pendingPostReducer.reducer;

同时我还有一个postsAPI,使用RTK Query获取全部帖子、用户帖子等数据:

export const postsApi = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: API_URL,
  }),
  tagTypes: ['Post'],
  endpoints: (build) => ({
    getPosts: build.query({
      query: (body) => ({
        url: `post/filter`,
        method: 'POST',
        body: body,
      }),
      providesTags: (result) =>
        result
          ? [
              ...result.data.map(({ id }) => ({ type: 'Post', id })),
              { type: 'Post', id: 'LIST' },
            ]
          : [{ type: 'Post', id: 'LIST' }],
    }),
  }),
});

export const { useGetPostsQuery } = postsApi;

我希望将两者结合,在创建帖子时执行mutation并使缓存失效,该如何实现?我曾尝试在RTK Query中存储自定义字段但未找到方法,猜测RTK Query仅用于缓存与查询操作。

解决方案

1. 在postsAPI中添加创建帖子的Mutation端点

在postsAPI的endpoints中新增一个创建帖子的mutation,通过invalidatesTags配置让帖子列表的缓存失效,这样提交成功后RTK Query会自动重新获取最新的帖子数据:

export const postsApi = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: API_URL,
  }),
  tagTypes: ['Post'],
  endpoints: (build) => ({
    getPosts: build.query({
      // 原getPosts配置不变
      query: (body) => ({
        url: `post/filter`,
        method: 'POST',
        body: body,
      }),
      providesTags: (result) =>
        result
          ? [
              ...result.data.map(({ id }) => ({ type: 'Post', id })),
              { type: 'Post', id: 'LIST' },
            ]
          : [{ type: 'Post', id: 'LIST' }],
    }),
    // 新增创建帖子的mutation
    createPost: build.mutation({
      query: (postData) => ({
        url: 'post', // 替换为实际的创建帖子接口地址
        method: 'POST',
        body: postData,
      }),
      // 让Post列表缓存失效,触发重新查询
      invalidatesTags: [{ type: 'Post', id: 'LIST' }],
    }),
  }),
});

// 导出mutation的Hook供组件使用
export const { useGetPostsQuery, useCreatePostMutation } = postsApi;

2. 在组件中结合pendingPost切片与Mutation提交数据

在需要提交帖子的组件中,先通过useSelector获取pendingPost中暂存的数据,再调用RTK Query提供的mutation Hook执行提交,提交成功后清空暂存的数据:

import { useSelector, useDispatch } from 'react-redux';
import { useCreatePostMutation } from './postsApi';
import { clearPendingPost } from './pendingPostReducer';

function CreatePostForm() {
  const dispatch = useDispatch();
  // 获取暂存的帖子数据
  const pendingPostData = useSelector(state => state.pendingPost.savedData);
  // 获取创建帖子的mutation函数和状态
  const [createPost, { isLoading, isSuccess }] = useCreatePostMutation();

  const handleSubmit = async () => {
    if (Object.keys(pendingPostData).length === 0) return;
    
    try {
      // 提交暂存的数据
      await createPost(pendingPostData).unwrap();
      // 提交成功后清空暂存数据
      dispatch(clearPendingPost());
    } catch (error) {
      // 处理提交失败的逻辑
      console.error('创建帖子失败:', error);
    }
  };

  return (
    <div>
      {/* 表单输入组件,通过dispatch(addPropertyToPendingPost)更新暂存数据 */}
      <button onClick={handleSubmit} disabled={isLoading}>
        {isLoading ? '提交中...' : '发布帖子'}
      </button>
    </div>
  );
}

export default CreatePostForm;

关键说明

你对RTK Query的定位判断是正确的:它确实专注于服务端数据的缓存管理与查询/更新操作,不适合存储本地临时的表单数据。这类本地暂存数据就应该用独立的Redux切片(比如你的pendingPost)来管理,两者的配合逻辑就是:

  • 用自定义切片存储本地未提交的临时数据
  • 用RTK Query的mutation提交数据到服务端,并通过invalidatesTags让相关缓存失效,自动触发数据刷新,保证前端展示与服务端数据一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 02:36:30