Redux-persist is persisting all reducers states except one, that is a combinedReducer.
Here is the code (or at least part of it):
store index.js
import { createStore, applyMiddleware, combineReducers, compose } from 'redux';
import { persistStore, persistReducer, persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web and AsyncStorage for react-native
import reduxReset from 'redux-reset'
import { createBlacklistFilter, createWhitelistFilter } from 'redux-persist-transform-filter';
import middlewares from "./middlewares";
import reducers from "./reducers";
import actions from "./actions";
const composeEnhancers =
(window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
const persistConfig = {
key: 'root',
storage,
transforms: [
createBlacklistFilter('ui', ['alerts']),
createBlacklistFilter('router', [])
]
}
export default (extraReducers={}, extraMiddlewares=[]) => {
const persistCombinedReducers = persistCombineReducers(persistConfig, {
...reducers,
...extraReducers
});
const store = createStore(
persistCombinedReducers,
composeEnhancers(
applyMiddleware(
...middlewares,
...extraMiddlewares
)
)
);
const persistor = persistStore(store);
return {store, persistor};
};
export { actions };
reducers/index.js
import ui from './ui'
import playlists from './playlists'
import user from './user';
import contents from './contents';
const rootReducer = {
playlists,
contents,
ui,
user
};
export default rootReducer;
reducers/user/index.js
This is the state.user reducer that is being persisted, so all OK!
import { createSelector } from "reselect";
import { handleActions } from "redux-actions";
import _ from "lodash";
import actions from "../../actions";
const initialState = {
profile: null,
// profile:
// "id"
// "name"
// "email"
// "gender"
// "photoUrl"
// "photoIsSilhouette"
relationships: [],
children: [],
contentFilterLanguages: []
};
const selectors = {};
selectors.profile = state => state.user.profile;
selectors.children = state => state.user.children;
selectors.getChild = (state, childId) => {
const { children } = state.user;
for (var i = 0; i != children.length; i++) {
if ( children[i].id == childId ) {
return children[i];
}
}
return undefined;
}
selectors.relationships = state => state.user.relationships;
selectors.loggedIn = createSelector(selectors.profile, profile => !!profile);
export { selectors };
export default handleActions(
{
[`${actions.user.login.action}_FULFILLED`]: (state, { payload }) => ({
...state,
profile: {
...payload.data.user,
token: payload.data.accessToken
}
}),
[`${actions.user.login.action}_REJECTED`]: () => initialState,
[`${actions.user.createGuestSession.action}_FULFILLED`]: (state, { payload }) => ({
...state,
profile: {
...payload.data.user,
token: payload.data.accessToken
}
}),
[`${actions.user.createGuestSession.action}_REJECTED`]: () => initialState,
[`${actions.user.logout.action}_FULFILLED`]: () => initialState,
[`${actions.user.logout.action}_REJECTED`]: () => initialState,
[`${actions.user.fetchChildren.action}_FULFILLED`]: (
state,
{ payload }
) => ({
...state,
relationships: payload.data,
children: payload.data.map(({ child }) => child)
})
},
initialState
);
reducers/ui/index.js
This is the state.ui reducer that is not being persisted. Not ok!!!!!
import { combineReducers } from 'redux';
import user from "./user";
import alerts from "./alerts";
export default combineReducers({
user,
alerts
});
reducers/ui/user.js
This is the state.ui.user reducer that is not being persisted. Not ok!!!!!
import { createSelector } from "reselect";
import { handleActions } from "redux-actions";
import _ from "lodash";
import actions from "../../actions";
const initialState = {
selectedChildId: undefined,
selectedPlaylist: {
play: undefined,
grow: undefined,
love: undefined
}
};
export default handleActions(
{
[`${actions.ui.user.selectSessionChild.action}`]: (state, { payload } ) => ({
...state,
selectedChildId: payload
}),
[`${actions.ui.user.selectPlaylist.action}`]: (state, { payload } ) => ({
...state,
selectedPlaylist:
payload
? { ...state.selectedPlaylist, [payload.streamType]: payload}
: undefined
})
},
initialState
);
Any idea? Thanks in advance.
@ejbp you can't use combineReducers and persistCombineReducers in combination since persistCombineReducers uses combineReducers under the hood. It says it in the documentation. Im surprised that browser console didn't throw an error
@ejbp were you able to resolve this issue? I'm encountering the same issue.
@nishtacular the problem was what @tommyalvarez described. After I corrected it, it started to work.
Here is my store.js file. I hope it helps:
import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, persistCombineReducers } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web and AsyncStorage for react-native
import { connectRouter, routerMiddleware } from 'connected-react-router'
import middlewares from "./middlewares";
import reducers from "./reducers";
import actions from "./actions";
const composeEnhancers =
(window && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
const persistConfig = {
key: 'root',
storage,
blacklist: ["ui", "router"]
}
export default ( {history, extraReducers={}, extraMiddlewares=[] } ) => {
const rootReducer = {
...reducers,
...extraReducers
};
const historyMiddleware = routerMiddleware(history); // Build the middleware for intercepting and dispatching navigation actions
const persistCombinedReducers = persistCombineReducers(persistConfig, rootReducer);
const store = createStore(
connectRouter(history)(persistCombinedReducers),
composeEnhancers(
applyMiddleware(
...middlewares,
historyMiddleware,
...extraMiddlewares
)
)
);
const persistor = persistStore(store);
return {store, persistor};
};
Most helpful comment
@nishtacular the problem was what @tommyalvarez described. After I corrected it, it started to work.
Here is my store.js file. I hope it helps: