Open lucasriondel opened 6 years ago
I'm seeing the same thing with the same setup. I don't think we're doing anything wrong though.
I ran into this as well, you have to blacklist users
from root
, not whitelist. In this example you can even remove the entire root persistor.
@evertbouw @sregg i only want availableUsers to be rehydrated, not the other properties.
as you've said @evertbouw , i have removed the root persistor, and i've changed it to :
const usersPersistConfig = {
key: 'users',
storage,
whitelist: ['availableUsers']
}
export default combineReducers({
users: persistReducer(usersPersistConfig, users),
error,
patient,
survey,
score
})
Also getting rehydrate twice, different setup
Hi @tonmanayo @lucasriondel did you find a solution for this, I am currently struggling with this
@nero2009 hi ! won't be able to help, sorry, but i managed to fixed it but i don't remember how... I'm working on a new project now.
any news about this?
@ammoradi in my case, apparently I blacklisted the reducers I didn't want to persist to Localforage twice(in my root reducer and store) that was what triggerred the persist/REHYDRATE action twice.
@nero2009 In my case I have this issue even without black/whitelist!
and both persist/PERSIST
and persist/REHYRATE
called twice
can i see your store and reducer?
@nero2009
import { applyMiddleware, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/es/storage';
import RootReducer, { SaveSubsetFilter } from '@redux/index';
const middlewares = [
thunk
];
let composer;
if (GLOBAL.__DEV__) {
GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;
const { composeWithDevTools } = require('redux-devtools-extension');
composer = composeWithDevTools;
middlewares.push(require('redux-immutable-state-invariant').default());
}
else {
composer = compose;
console.log = () => {};
console.warn = () => {};
console.error = () => {};
}
const config = {
timeout: 12000,
key: 'root',
storage,
whitelist: ['core'],
debug: false,
transforms: SaveSubsetFilter
};
const enhancer = composer(
applyMiddleware(...middlewares)
);
const reducer = persistReducer(config, RootReducer);
const store = createStore(reducer, enhancer);
const persistor = persistStore(store);
export default function configureStore() {
if (module.hot) {
module.hot.accept(() => {
const nextRootReducer = require('@redux/index').default;
const nextReducer = persistReducer(config, nextRootReducer);
store.replaceReducer(nextReducer);
});
}
return { persistor, store };
}
@ammoradi from your store.js, I don't know exactly what might be causing it but I think you should try probing your configureStore
function
Not sure if this could be helpful for anyone, but I was having a similar problem, except the second hydration was breaking my app by updating a nested persist with an undefined payload. I also needed the second hydration because of the nested persist. I realized I needed to blacklist that property on the root config, and not whitelist it on the nested config. Here's an example:
nested persist for auth (I needed this due to the hardSet
state reconciliation):
const authConfig = {
key: 'auth',
storage,
stateReconciler: hardSet,
}
export default authReducer(authConfig, auth)
rootReducer:
export default combineReducers({
authReducer,
form: FormReducer,
user,
})
root persist:
const persistConfig = {
key: 'root',
blacklist: ['auth'],
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
const store = createStore(persistedReducer, initialState, enhancer)
I know this might not be completely aligned with the original issue, but I came across this issue in the search to resolve my bug, so I'm leaving it here in case it could be helpful to anyone else.
I ran into this as well, you have to blacklist
users
fromroot
, not whitelist. In this example you can even remove the entire root persistor.
This is the solution. I think others, like me, have misunderstood the correct way to persist certain keys of a nested reducer state. We have to blacklist the nested reducer state first, then whitelist the individual keys we want to persist.
For me this happened where in the onComplete callback of the persistStore I was updating the state of the component which parented the PersistGate. Shifting the state related logic to the root within the PersistGate instead solved this for me.
store is rehydrated twice
HERE IS MY STORE FILE:
`import { routerMiddleware } from 'connected-react-router'
import { applyMiddleware, compose, createStore } from 'redux';
import { createLogger } from 'redux-logger';
import createSagaMiddlware from 'redux-saga';
import createRootReducer from '../state/reducers';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { createBrowserHistory } from "history";
const history = createBrowserHistory();
const persistConfig = {
key: 'root',
storage,
}
const sagaMiddleware = createSagaMiddlware();
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const getAppliedMiddleware = (routerhistory: any) => {
if (process.env.NODE_ENV === 'development') {
return applyMiddleware(
sagaMiddleware,
routerMiddleware(routerhistory),
createLogger(),
);
}
return applyMiddleware(
sagaMiddleware,
routerMiddleware(routerhistory),
createLogger(),
)
}
export const STORE = createStore(
persistReducer(persistConfig, createRootReducer(history)),
{},
composeEnhancers(
getAppliedMiddleware(history),
),
);
`
HERE IS MY APP.TSX FILE:
`
import "./styles/base.scss";
import { ConnectedRouter } from "connected-react-router";
import { createBrowserHistory } from "history";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { Route as Router, Switch } from "react-router";
import { Route } from "react-router-dom";
const history = createBrowserHistory();
import {STORE} from "./store/index";
import { PersistGate } from "redux-persist/integration/react";
import { persistStore } from "redux-persist";
import HeaderComponent from "./components/home/header_component";
import { AppRoutes } from "./utils/routes";
ReactDOM.render(
<Provider store={STORE}>
<PersistGate loading={null} persistor={persistStore(STORE)}>
<ConnectedRouter history={history}>
<Router>
<HeaderComponent />
<div className="page-wrapper">
<Switch>
{AppRoutes.map((route: any) => {
return <Route key={route.path} {...route} />;
})}
</Switch>
</div>
</Router>
</ConnectedRouter>
</PersistGate>
</Provider>,
document.getElementById("app")
);
`
ISSUE I AM FACING: Same data rehydrating twice:
It can happen when there are 2 instances of redux-persist.
I had issue when I have 1 bundle connected and second, which replaces the first one. In result only 1 app exists, but by fact that there are 2 same bundles created this issue. I noticed that first rehydrate had previous config, which conflicted with current one.
I know it's important to stay hydrated but my store is being hydrated twice here :
store.ts
app.tsx
at startup:
I may do something wrong since the first hydration bypasses whitelist rules.
Any idea ?