我正在使用Redux工具包,Redux持久和RTK查询在我的项目。
我已经用Redux Toolkit和Redux Persists配置了存储。设法使用Redux Persists持久化数据。目前我可以使用useSelector挂钩将持久化数据放入我的组件层。
我有其他的API定义,这是由RTK查询完成的。我有一个文件与所有的API定义由RTK查询的createApi,baseQuery等函数完成。
我的“问题”是:
- 在组件层中的存储初始化之前,我无法访问持久化数据。我可以访问数据,因为useSelector挂钩正在使呈现器等待,直到persistGate将持久化数据添加到存储中
- 但是在同一个文件中,我调用了在另一个文件中定义的那些查询函数钩子,在这个文件中,我需要恢复持久化数据。
// Main App.js
const App = () => {
return (
<Provider store={store}>
<PersistGate persistor={persistor}>
<Route path="/orderlist" element={<OrdersList />} />
</PersistGate>
</Provider>
)
}
// Store Configuration
const persistConfig = {
key: 'root',
storage: storage,
blacklist: [],
whitelist: ['auth']
}
const reducers = {
[authSlice.name] : authSlice.reducer,
}
const rootReducer = combineReducers(reducers)
const persistedReducer = persistReducer(persistConfig, rootReducer)
export const token = (state) => state.persistedReducer
export const store =
configureStore({
reducer: {
persistedReducer,
[api.reducerPath]: api.reducer,
order: orderSlice.reducer,
[userApi.reducerPath]: userApi.reducer
// [orderSlice.name] : orderSlice.reducer,
// [api.reducerPath]: api.reducer,
// order: orderSlice.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
}
}).concat([
api.middleware,
userApi.middleware
]),
})
// Api Definitions - where I needed the persisted data
import { createApi, fetchBaseQuery, retry } from '@reduxjs/toolkit/query/react'
import { rootState } from '../store'
// Root state is not working here, this file execute the code before store intiatization
// I need the rehydrated state here
// Please check my store configuration
// const storeSubscription = store.getState()
// console.log(rootState)
// Create Our baseQuery Instance
const baseQuery = fetchBaseQuery({
baseUrl: 'http://34.229.141.62/api/v1/',
})
// console.log(baseQuery)
const baseQueryWithRetry = retry(baseQuery, { maxRetries: 1 })
export const userApi = createApi({
reducerPath: 'USER_API_REDUCER_KEY',
baseQuery: baseQueryWithRetry,
// prepareHeaders: (headers, { getState }) => {
// const token = getState().order.isToken
// console.log(token)
// // If we have a token set in state, let's assume that we should be passing it.
// if (token) {
// headers.set(`Bearer ${token}`)
// }
// return headers
// },
tagTypes: ['Orders'],
endpoints: builder => ({}),
serializeQueryArgs: ({ endpointName, queryArgs }) => endpointName
})
// Endpoint injections in create API
import { createSelector, createEntityAdapter } from "@reduxjs/toolkit";
import { userApi } from "./userApi";
const ordersAdapter = createEntityAdapter({
// selectId: (order) => order.id,
sortComparer: (a,b) => b._id.localeCompare(a._id)
})
const initialState = ordersAdapter.getInitialState()
export const extendedApiSlice = userApi.injectEndpoints({
endpoints: builder => ({
getOrders: builder.query({
query: () => ({
url: 'orders/userOrders',
}),
transformResponse: (responseData, meta, arg) => {
let i = 1
const loadedOrders = responseData.orders.map(order => {
if(!order?.id) order.id = i++
// console.log(order)
return order
})
return ordersAdapter.setAll(initialState, loadedOrders)
},
providesTags: (result, error, arg) => [
// { type: 'Orders', id: 'LIST' },
'Orders'
]
}),
deleteOrders: builder.mutation({
// query: ({id}) => ({
query: (body) => ({
// url: `orders/cancel/${id}`,
url: `orders/cancel/`,
method: 'POST',
body: body,
refetchOnMountOrArgChange: true,
invalidatesTags: (result, error, arg) => [
'Orders'
]
})
})
}),
})
// console.log(ordersAdapter)
export const {
useGetOrdersQuery,
useDeleteOrdersMutation
} = extendedApiSlice
// console.log(extendedApiSlice)
export const selectOrdersResult = extendedApiSlice.endpoints.getOrders.select()
export const deleteOrdersResult = extendedApiSlice.endpoints.deleteOrders.initiate()
export const selectdeleteOrderResult = extendedApiSlice.endpoints.deleteOrders.select()
// export const useDeleteOrdersMutation = extendedApiSlice.endpoints.deleteOrders.useMutation()
// console.log(deleteOrdersResult)
// console.log(selectdeleteOrderResult)
export const selectOrdersData = createSelector(
selectOrdersResult,
ordersResult => ordersResult.data
)
// console.log(selectOrdersData)
export const {
selectAll: selectAllOrders,
selectById: selectOrderById,
selectIds: selectOrderIds
} = ordersAdapter.getSelectors(state => selectOrdersData(state) ?? initialState)
// Component where I am calling those query hooks from create API
import { token } from "../../Servicepage/store";
import { useDispatch, useSelector } from "react-redux";
import { useGetOrdersQuery, useDeleteOrdersMutation, selectAllOrders, selectOrderById, selectOrderIds } from "../../Servicepage/services/userSlice";
import Button from "./Button";
import { addToken, resOrder, selectCount } from "../../Servicepage/services/orderSlice"
import { useEffect } from "react";
const OrdersList = () => {
const dispatch = useDispatch()
const authState = useSelector(token)
const Token = authState.auth.accessToken
// console.log(Token)
// dispatch(addToken({ isToken: false }))
useEffect(() => {
dispatch(addToken({ isToken: Token}))
}, [])
const completeOrderState = useSelector(selectCount)
// console.log(completeOrderState)
const {
isLoading,
isSuccess,
refetch,
isError,
error
} = useGetOrdersQuery()
const orderIds = useSelector(selectOrderIds)
const orderIdz = useSelector((state) => selectOrderById(state, 1))
const orderAll = useSelector(selectAllOrders)
const [deletePost] = useDeleteOrdersMutation()
let content;
if (isLoading) {
content = <p>"Loading..."</p>
} else if (isSuccess) {
// console.log(orderIds)
// console.log(orderIdz)
console.log(orderAll)
// deletePost({ id: 'JBCS000001' })
content = orderAll.map((orders, indx) => {
return (
<div key={indx}>
<p><strong>Order List</strong></p>
<p>{orders.id}</p>
<p>Total Amount: {orders.totalAmount}</p>
<p>Email: {orders.email} </p>
<p>OrderId: {orders.orderId} </p>
<p>Status: {orders.status}</p>
<Button orderID={orders.orderId} />
</div>
)
})
}
return (
<div>
{content}
</div>
)
}
到目前为止,我还没有找到任何方法将持久化数据导入我的API定义,因为我的API定义钩子总是在持久化数据导入到我的存储之前调用,这在组件中被应用程序的persistGate延迟。
有什么问题尽管问。
2条答案
按热度按时间dtcbnfnu1#
到目前为止,我还没有找到一个解决方案。但我已经创建了在组件层检查令牌的功能,然后调用这些查询,在访问这些查询之前,我通过另一个切片中的组件副作用来调度令牌,这些副作用通常不会持久化。
还在等一个好的解决办法。
我尝试过使用redux-persistent storage调用选项,但也没有成功,因为我需要解析持久化数据。
ktca8awb2#
我找到了一个访问非组件文件中存储的示例。
https://redux.js.org/faq/code-structure#how-can-i-use-the-redux-store-in-non-component-files
不确定如何使用RTK查询实现它,Redux保留reducer。