How to edit persistent store from react-persist during runtime - reactjs

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 }
}

Related

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

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.

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

Why is Redux-Persist not persisting the store

Hi there everyone I was messing around with react(redux to be precise) and came across a problem. When I refresh the page redux store does as well everything returns to its initial value, I googled the problem and found out that I have to use redux-persist. However even that is not working, I think the problem is with how I configured redux-persist but I could be wrong.
The code below is how I went about the redux-persist configuration.
// configureStore.js
import { createStore, applyMiddleware } from "redux";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import rootReducer from "../reducers/index";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
const persistConfig = {
key: "root",
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = createStore(
persistedReducer,
composeWithDevTools(applyMiddleware(thunk))
);
export const persistedStore = persistStore(store);
The code below shows how I went about making the rootReducer.
// index.js
import { combineReducers } from "redux";
import { reducer as formReducer } from "redux-form";
import authReducer from "./auth";
import messageReducer from "./message";
import chatroomReducer from "./chatroom";
import { LOGOUT_SUCCESS } from "../actions/authTypes";
const apiReducer = combineReducers({
authReducer,
messageReducer,
chatroomReducer,
form: formReducer,
});
const rootReducer = (state, action) => {
if (action.type === LOGOUT_SUCCESS) {
state = undefined;
}
return apiReducer(state, action);
};
export default rootReducer;
And the code below is the index.js that comes when creating the react app.
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { PersistGate } from "redux-persist/integration/react";
import { Provider } from "react-redux";
import { store, persistedStore } from "./Redux/configureStore";
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistedStore}>
<React.StrictMode>
<App />
</React.StrictMode>
</PersistGate>
</Provider>,
document.getElementById("root")
);
reportWebVitals();
Can anyone tell me what is wrong with my code? If you need additional info please let me know.
Try configuring the whitelist, where you must indicate which reducers to store.
Remember to import the reducers before adding them to the list
import navigation from "./reducers/navigation";
// WHITELIST
const persistConfig = {
key: 'root',
storage: storage,
whitelist: ['navigation'] // only navigation will be persisted
};
First, you need to import storage from Async
import AsyncStorage from '#react-native-community/async-storage';
Use WhiteList like this
const persistConfig = {
key: 'root',
storage: AsyncStorage,
whitelist: [
'user'
],
};
"user" is the specific root reducer you want to store
As per this answer, you also need to clear out the redux-persist storage when you catch the LOGOUT_SUCCESS action.
First, you need to import the appropriate storage engine and then clear it out completely.
const rootReducer = (state, action) => {
if (action.type === SIGNOUT_REQUEST) {
// for all keys defined in your persistConfig(s)
storage.removeItem('persist:root')
// storage.removeItem('persist:otherKey')
return appReducer(undefined, action);
}
return appReducer(state, action);
};

How to persist redux store to local storage rather than async storage in react native

I am using redux-persist to persist state of my app. By default it persist state inside AsyncStorage but I want it to be in localStorage. There is nothing about this in official docs as far as react-native is concerned.
This is my code till now:
import { persistStore, persistCombineReducers } from 'redux-persist';
import storage from 'redux-persist/es/storage';
const config = {
key: 'root',
storage,
debug: true
}
export const ConfigureStore = () => {
const store = createStore(
persistCombineReducers(config,{
dishes,
comments,
promotions,
leaders,
favorite
}),
applyMiddleware(thunk)
);
const persistor = persistStore(store)
return {persistor, store};
}
Can I do something like this:
import storage from 'redux-persist/es/localStorage';
...
storage: storage
Please help me on the topic if anyone has ever used it before. Thank You!
One thing i noticed is that you import says
import storage from 'redux-persist/es/storage';
But in the documentation is used
import storage from 'redux-persist/lib/storage'
Otherwise you can use this approach like in the documentation.
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store, persistor }
}
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};

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