We are using this with LZ-compression, but are running into problems especially on Firefox with restoring state. Firefox often can't decompress the state we have put in there with LZ (don't know why), but this results in the state being "restored" to null.
How would you recommending handling this, so instead of restoring a key state to null, it would just act as if there was nothing to restore, and use the default state defined in the reducer?
This is our current setup for reference:
persistStore(store, {
whitelist: ['chat', 'contacts', 'user'],
transforms: [chatMessageHistoryTransform, compressor]
}, rehydrationCallback);
So for example the LZ decompress of "contacts" might fail, and then we get out null instead of the default (an empty array []).
It seems that Firefox only works with LZ (and localStorage) if you use UTF16. I have created an issue on redux-persist-transform-compress.
But the question stands: how to handle if a transform is not able to restore state, and use default state instead?
Another update: I tried validating the rehydrated state in my reducer on the REHYDRATE event, but because of autoHydrate.js#L37 my (fixed) reducer state is always overwritten by the incoming garbage from the corrupted stored state.
I finally ended up writing middleware, that will modify the REHYDRATE payload if it is invalid. Don't know if this is the "correct" way to do it, but here is the code:
import { REHYDRATE } from 'redux-persist/constants';
function validate(state, value) {
return state
&& typeof state === typeof value
&& Object.keys(state).every((key) => key in value);
}
const validateRehydrateMiddleware = store => next => action => {
switch (action.type) {
case REHYDRATE:
if (action.payload && typeof action.payload === 'object') {
const newPayload = {};
const state = store.getState();
Object.keys(action.payload).forEach((key) => {
if (validate(state[key], action.payload[key])) {
newPayload[key] = action.payload[key];
}
});
action.payload = newPayload;
}
break;
}
return next(action);
};
export default validateRehydrateMiddleware;
@omichelsen im going to need to invalidate the persisted state based on a timestamp on the state. Have you stuck with this custom middleware approach?
Yes, it has been working well for us so far.
thanks man
This hasn't been responded to in a long while, so I'm going to mark it as stale. Please feel free to continue the conversation and I'll reopen.
Most helpful comment
Another update: I tried validating the rehydrated state in my reducer on the REHYDRATE event, but because of autoHydrate.js#L37 my (fixed) reducer state is always overwritten by the incoming garbage from the corrupted stored state.
I finally ended up writing middleware, that will modify the REHYDRATE payload if it is invalid. Don't know if this is the "correct" way to do it, but here is the code: