React Redux Persist : How to control when persist data in indexeddb - reactjs

I'm working on a React/redux application using redux-persist and I have a huge amount of data to persist, I want to be able to persist my Redux Store ONLY when I click on a button, otherwise I don't want to store my data.
This is my store :
import {
legacy_createStore as createStore,
combineReducers,
applyMiddleware
} from "redux";
import { composeWithDevTools } from "redux-devtools-extension/developmentOnly";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist-indexeddb-storage";
import thunk from "redux-thunk";
import dataReducer from "./reducers/dataReducer";
const reducer = combineReducers({
data: dataReducer
});
const persistConfig = {
key: "STORE",
storage: storage("STORE")
};
const persistedReducer = persistReducer(persistConfig, reducer);
const initialState = {};
const middleware = [thunk];
const composeEnhancers = composeWithDevTools({
features: {
dispatch: true // dispatch custom actions or action creators
}
});
const store = createStore(
persistedReducer,
initialState,
composeEnhancers(
applyMiddleware(...middleware)
// other store enhancers if any
)
);
const persistor = persistStore(store);
export { persistor };
export default store;
My Index.js look like this :
And I've create a component to show my data :
By doing that : the redux persist data starting from the first render (this is the indexedDb)
What I'm looking for is to set my indexedDB only when I click on the button and trigger the persistData function.
This is my code , So if you have an idea how to achieve this please.

Related

Clear the redux store after logout

I have created a redux store below, the only thing I want to clear the redux store when user logout from the application, so store having the latest and updated data of currently logged user.
import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import rootReducer from './Reducers';
import { sessionService } from 'redux-react-session';
import thunk from 'redux-thunk';
const persistedReducer = persistReducer({ key: 'root', storage }, rootReducer);
const composeEnhancers =
(typeof window !== 'undefined' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
compose;
export const store = createStore(
persistedReducer,
composeEnhancers(
applyMiddleware(thunk)
)
);
export const persistor = persistStore(store);
sessionService.initSessionService(store);
The above snippet I wrote to create the store using redux persist
please suggest

How to get middlewares from getDefaultMiddleware without deprecation message

I'm using a different setup for initializing the redux store (I don't want to use the configureStore method from redux-toolkit) for the purpose of injecting reducers on runtime.
import {
createStore,
combineReducers,
applyMiddleware,
createImmutableStateInvariantMiddleware,
} from "#reduxjs/toolkit";
import { composeWithDevTools } from "#redux-devtools/extension";
import { createCustomMiddleWare} from "./myCustomMiddleWare";
const staticReducers = {};
const middlewares = [
createImmutableStateInvariantMiddleware(),
createCustomMiddleWare(),
];
const createReducer = (asyncReducers = {}) =>
combineReducers({
...staticReducers,
...asyncReducers,
});
export const initializeStore = (initializeState = {}) => {
const store = createStore(
createReducer(),
initializeState,
composeWithDevTools(applyMiddleware(...middlewares))
);
store.asyncReducers = {};
store.injectReducer = (key, reducer) => {
store.asyncReducers[key] = reducer;
store.replaceReducer(createReducer(store.asyncReducers));
return store;
};
return store;
};
export default initializeStore;
I was wondering wether there is a way to add Thunk middleware from redux-toolkit (without installing the redux-thunk package seperately)
I tried using the getDefaultMiddleware() method from redux-toolkit which imports three default middlewares that ships with redux-toolkit including thunk, but since I'm not using it as paramether for the configureStore's middleware callback, I get this error that getDefaultMiddleware is deprecated.
I was able to import one of the default middlewares by using createImmutableStateInvariantMiddleware() function that I found in the official documentations but I could not find a way to import thunk or serlizied middlewares (two other default middlewares of redux-toolkit)
The answer would be to use configureStore and using the middleware callback option.
There is really no good reason that would be using createStore here, that could come down to
const store = configureStore({
reducer: createReducer(),
preloadedState: initializeState,
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(createCustomMiddleWare())
})

How to edit persistent store from react-persist during runtime

We are using react-persist and we have created a persistent redux-store during initialization.
We'd like to toggle the persistence state of a reducer through persistConfig after initialization (or during runtime).
Is this possible ?
This is how we create our store during initialization:
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web and AsyncStorage for react-native
import hardSet from 'redux-persist/lib/stateReconciler/hardSet'
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
whitelist: ['visibilityFilter'] // navigation will not be persisted
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer);
let persistor = persistStore(store);
return { store, persistor }
}

How to set up redux-persist with thunk, middleware and immutable JS?

I am trying to get redux-persist working and cannot work out how to do it with the way my app is currently set up.
/**
* Create the store with dynamic reducers
*/
import { createStore, applyMiddleware, compose } from 'redux';
import { fromJS } from 'immutable';
import { routerMiddleware } from 'react-router-redux';
import createSagaMiddleware from 'redux-saga';
import thunk from 'redux-thunk';
import createReducer from './reducers';
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState = {}, history) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
const middlewares = [
sagaMiddleware,
thunk,
routerMiddleware(history),
];
const enhancers = [
applyMiddleware(...middlewares),
];
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
/* eslint-disable no-underscore-dangle */
const composeEnhancers =
process.env.NODE_ENV !== 'production' &&
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// TODO Try to remove when `react-router-redux` is out of beta, LOCATION_CHANGE should not be fired more than once after hot reloading
// Prevent recomputing reducers for `replaceReducer`
shouldHotReload: false,
})
: compose;
/* eslint-enable */
const store = createStore(
createReducer(),
fromJS(initialState),
composeEnhancers(...enhancers)
);
// Extensions
store.runSaga = sagaMiddleware.run;
store.injectedReducers = {}; // Reducer registry
store.injectedSagas = {}; // Saga registry
// Make reducers hot reloadable, see http://mxs.is/googmo
/* istanbul ignore next */
if (module.hot) {
module.hot.accept('./reducers', () => {
store.replaceReducer(createReducer(store.injectedReducers));
});
}
return store;
}
Where am I supposed to add redux-persist in here to make it connect to the store and save to localstorage?
I have tried a lot of different ways, all wrong, with a huge range of errors.. So no point posting all of them up.
Thanks in advance for helping :)
I'm not sure if this is of any use as I'm using redux-thunk and redux-localstorage (instead of redux-persist), but this works for me:
import { createStore, compose, applyMiddleware } from 'redux';
import rootReducer from '../reducers/rootReducer';
import thunk from 'redux-thunk';
import persistState from 'redux-localstorage';
const enhancer = compose(
applyMiddleware(thunk),
persistState(/*paths, config*/)
);
export default function configureStore() {
return createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__(),
enhancer
);
}

action.rehydrate is not a function

I have been getting the following error since sometime in my console, i have no idea what it means and why it is originating. Please spread some light on this matter.
it says:
persistReducer.js:50 Uncaught TypeError: action.rehydrate is not a function
at _rehydrate (persistReducer.js:50)
at persistReducer.js:54
redux-persist version on package.json: "^5.6.11"
locked version: "5.9.1"
Store configuration code:
import thunk from 'redux-thunk';
import { persistStore } from 'redux-persist';
import { History, createBrowserHistory } from 'history';
import { createUserManager, loadUser } from "redux-oidc";
import { routerReducer, routerMiddleware } from 'react-router-redux';
import { createStore, applyMiddleware, compose, combineReducers, GenericStoreEnhancer, Store, StoreEnhancerStoreCreator, ReducersMapObject } from 'redux';
import * as StoreModule from './reducers';
import { ApplicationState, reducers } from './reducers';
import userManager from "./utils/userManager";
// Create browser history to use in the Redux store
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
const history = createBrowserHistory({ basename: baseUrl });
export default function configureStore(history: History, initialState?: ApplicationState) {
// Build middleware. These are functions that can process the actions before they reach the store.
const windowIfDefined = typeof window === 'undefined' ? null : window as any;
// If devTools is installed, connect to it
const devToolsExtension = windowIfDefined && windowIfDefined.__REDUX_DEVTOOLS_EXTENSION__ as () => GenericStoreEnhancer;
const createStoreWithMiddleware = compose(
applyMiddleware(thunk, routerMiddleware(history)),
devToolsExtension ? devToolsExtension() : <S>(next: StoreEnhancerStoreCreator<S>) => next
)(createStore);
// Combine all reducers and instantiate the app-wide store instance
const allReducers = buildRootReducer(reducers);
const store = createStoreWithMiddleware(allReducers, initialState) as Store<ApplicationState>;
loadUser(store, userManager);
// Enable Webpack hot module replacement for reducers
if (module.hot) {
module.hot.accept('./reducers', () => {
const nextRootReducer = require<typeof StoreModule>('./reducers');
store.replaceReducer(buildRootReducer(nextRootReducer.reducers));
});
}
const persistor = persistStore(store);
return { store, persistor };
}
function buildRootReducer(allReducers: ReducersMapObject) {
return combineReducers<ApplicationState>(Object.assign({}, allReducers, { routing: routerReducer }));
}
// Get the application-wide store instance, prepopulating with state from the server where available.
const initialState = (window as any).initialReduxState as ApplicationState;
export const { store, persistor } = configureStore(history, initialState);
if you are working on localhost and using redux-devtools try to check Access File Url checkbox on extension options.
you can manage your chrome extensions by typing chrome://extensions/ in the address bar or by going to the setting and chose extensions from left menu.
I get this error when using redux devtools, remove this and it should go away.
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
Your code is using API of an older redux-persist version.
Refer to Basic Usage for the updated API:
import { persistStore, persistReducer } from 'redux-persist'
const persistConfig = {
key: 'root',
storage,
}
const allReducers = persistReducer(persistConfig, buildRootReducer(reducers));

Resources