-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rtk-query fetch data Stored in the redux-persist #1400
Comments
I'm not sure what the actual question here is, but @phryneas has commented on this in multiple places. I'd recommend reading this: https://stackoverflow.com/questions/67943867/what-happens-when-i-use-rtk-query-with-redux-persist |
I hope that the data stored in the store is only the interface data returned by the back end, and there is no loading or status。eg. |
@kuangshp That does not even seem to be a RTK-Query internal state, but some derived data...? I don't know what you are persisting there. But generally, even with us adding support for rehydration in the future, you will have to persist the data structures as they are, not just whatever you like. (And generally, you probably should not be persisting an api cache at all) |
Hello @kuangshp were you able to work rtk-query with redux-persists correctly I also need to make it work together in my react native app. I need redux-persists to save some data and for future offline support. I configure similar to your code but I see that after some time I enter again to my component but it does not refetch new data. |
@jonra1993 generally I can only advise against persisting RTK-Query state at this moment. It will be possible in RTK 1.7 to rehydrate with helpers we will be providing, but with the current version of RTK if you just persist and rehydrate it, you will also rehydrate component subscriptions of components that are not there (so stuff will never be cache-collected) and even worse, if you rehydrate a query that was currently in "pending" state, that state will never be left and it will be impossible to fetch that state again. You can install the experimental build from #1277 and configure rehydration like shown in https://github.com/phryneas/ssr-experiments/blob/126262fcce7f8b788df3670dbc061362c65b6b9e/nextjs-blog/lib/pokemonApi.ts#L8-L12 , but that might still change a bit before release. |
Hello, @phryneas thanks for the response I am going to check it. I found an alternative solution meanwhile. I have a persistent reducer and others not persisted using rtk-query. More description can be found here maybe someone is facing a similar issue. |
You can also just persist the whole store, but |
Hello @phryneas when I do that I get this warning |
@jonra1993 you get the lower warning because you keep persisting and restoring RTK-Q using a non-supported method of doing so. you will have the state from last application and the middleware from the current application and they do not belong together. |
Hello, @phryneas thanks for your recommendation was the best "using the blacklist". I reset states on logout and due to I located API slides on configureStore they were not affected and the cache was not invalidated. "resetAppAction" is dispatched on logout. This current setup worked perfectly but sometimes I get the second warning. store.ts import { useDispatch as useReduxDispatch, useSelector as useReduxSelector } from 'react-redux';
import type { TypedUseSelectorHook } from 'react-redux';
import type { ThunkAction } from 'redux-thunk';
import type { Action } from '@reduxjs/toolkit';
import { configureStore } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query/react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from "redux-persist"
import { encryptTransform } from 'redux-persist-transform-encrypt';
import thunk from 'redux-thunk';
import { ENABLE_REDUX_DEV_TOOLS } from 'src/constants';
import rootReducer from './rootReducer';
import { storiesApi } from 'src/services/storiesService'
const encryptor = encryptTransform({
secretKey: 'my-super-secret-key',
onError: function (error) {
// Handle the error.
},
});
const persistConfig = {
key: 'root',
storage: AsyncStorage,
blacklist: [
storiesApi.reducerPath,
],
timeout: null,
transforms: [encryptor],
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = configureStore({
reducer: persistedReducer,
devTools: ENABLE_REDUX_DEV_TOOLS,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat(
thunk,
storiesApi.middleware,
),
});
// optional, but required for refetchOnFocus/refetchOnReconnect behaviors
// see `setupListeners` docs - takes an optional callback as the 2nd arg for customization
setupListeners(store.dispatch)
export const persistor = persistStore(store);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export type AppThunk = ThunkAction<void, RootState, null, Action<string>>;
export const useSelector: TypedUseSelectorHook<RootState> = useReduxSelector;
export const useDispatch = () => useReduxDispatch<AppDispatch>(); rootReducer.ts import { combineReducers } from '@reduxjs/toolkit';
import { reducer as authReducer } from 'src/redux/slices/auth';
import { reducer as storiesReducer } from 'src/redux/slices/stories';
import { storiesApi } from 'src/services/storiesService'
const appReducer = combineReducers({
auth: authReducer,
stories: storiesReducer,
[storiesApi.reducerPath]: storiesApi.reducer,
});
const rootReducer = (state, action) => {
if (action.type === 'RESET_APP') {
state = undefined;
}
return appReducer(state, action);
};
export const resetAppAction = () => dispatch => {
console.log('Reset Redux Store');
dispatch({ type: 'RESET_APP' });
};
export default rootReducer; |
@phryneas Currently I am trying to create an infinite scroll list, so each time a new response arrives it should be appended into the last state as a concatenation. lastApiState = lasApiState.concat(newApiResponse) Is there any way to create an action that is able to generate a dispatch that mutates the apiState manually not using an API query? I made use of extraReducers in a slide in order to have a 'copy' of states each time a new Api response arrives, but I think if there is any way to mutated API state it could be better. Please let me know if there is any way I can do that. Thanks in advance. const slice = createSlice({
name: 'stories',
initialState,
reducers: {
},
extraReducers: (builder) => {
builder.addMatcher(storiesApi.endpoints.getStories.matchFulfilled,
(state: IStoriesState, action: PayloadAction<IListResponse>) => {
const data = action.payload;
console.log('addMatcher getStories')
const lastStories = [...state.posts];
if(data.currentPage === 1) state.posts = data.results;
else state.posts = [...lastStories, ...data.results];
}
},
}); |
Do not worry I found your response on StackOverflow I am going to try to implement it |
I want to persist the data requested by RTk-Query into the browser's localstorage. I've already done that using redux-persist, but looking at the data in localstorage, Not the data that I want to return in transformResponse, but one that includes a lot of state classes
The text was updated successfully, but these errors were encountered: