使用RTK获取数据后如何自动更新Redux Store?
解决方案
你的问题核心是RTK Query获取到的数据默认存在自身的reducer中,没有和你自定义的collection slice关联,同时你的slice里的状态更新逻辑还存在格式错误,以下是具体修正步骤:
1. 修正自定义Slice的状态更新逻辑
你当前的appendCollections reducer把数组当成对象处理,会导致数据格式混乱。根据需求改为数组的替换或追加逻辑:
import { createSlice } from "@reduxjs/toolkit"; const initialState = { allCollections: [], isError: false, isSuccess: false, isLoading: false, message: "", }; export const collectionsSlice = createSlice({ name: "collection", initialState, reducers: { // 替换全部收藏数据 setCollections: (state, action) => { state.allCollections = action.payload; }, // 追加收藏数据(用于分页加载场景) appendCollections: (state, action) => { state.allCollections = [...state.allCollections, ...action.payload]; }, // 更新加载状态 setLoading: (state, action) => { state.isLoading = action.payload; }, // 更新错误状态 setError: (state, action) => { state.isError = action.payload.isError; state.message = action.payload.message; }, }, }); export const { setCollections, appendCollections, setLoading, setError } = collectionsSlice.actions; export default collectionsSlice.reducer;
2. 在RTK Query中同步数据到自定义Slice
修改openseaService,利用onQueryStarted钩子在请求生命周期中触发自定义slice的action,自动同步数据:
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react"; // 导入自定义slice的action import { setCollections, setLoading, setError } from "../features/collections/collectionSlice"; export const openSeaApi = createApi({ reducerPath: "collectionsApi", baseQuery: fetchBaseQuery({ baseUrl: `https://testnets-api.opensea.io/api/v1`, }), endpoints: (builder) => ({ retreiveCollections: builder.query({ query: ({ asset_owner, offset, limit }) => `collections?asset_owner=${asset_owner}&offset=${offset}&limit=${limit}`, // 请求生命周期钩子:同步状态到自定义slice onQueryStarted: async (arg, { dispatch, queryFulfilled }) => { dispatch(setLoading(true)); try { const { data } = await queryFulfilled; // OpenSea接口返回结构为{ collections: [...] },需取对应字段 dispatch(setCollections(data.collections)); dispatch(setLoading(false)); dispatch(setError({ isError: false, message: "" })); } catch (err) { dispatch(setLoading(false)); dispatch(setError({ isError: true, message: err.error?.message || "获取收藏数据失败" })); } }, }), }), }); export const { useRetreiveCollectionsQuery } = openSeaApi;
3. 组件代码保持不变
现在你的组件无需额外处理,RTK Query会自动在请求完成后把数据同步到collection slice中:
const user = JSON.parse(localStorage.getItem("user")); const { data, isError, isLoading } = useRetreiveCollectionsQuery({ asset_owner: user?.account, offset: 0, limit: 300, });
可选优化:直接使用RTK Query内置状态
如果不需要额外的自定义状态逻辑,你可以直接删除collectionSlice,直接使用RTK Query返回的状态和数据,这样更简洁:
const user = JSON.parse(localStorage.getItem("user")); const { data: collectionsRes, isError, isLoading } = useRetreiveCollectionsQuery({ asset_owner: user?.account, offset: 0, limit: 300, }); // 直接从RTK Query返回的数据中提取收藏列表 const collections = collectionsRes?.collections || [];
内容的提问来源于stack exchange,提问作者Ghost
相关产品推荐
相关产品推荐

