Open lid2000 opened 8 years ago
Good catch. It seems the most elegant solution is for redux-persist's persistor.rehydrate
to detect if the incoming state is a string and deserialize accordingly.
A little bit better solution is writing your own serializer and deserializer:
import { createStore, compose } from 'redux';
import { persistStore, autoRehydrate } from 'redux-persist';
import crosstabSync from 'redux-persist-crosstab';
const finalCreateStore = compose(autoRehydrate())(createStore);
const store = finalCreateStore(reducer);
const persistor = persistStore(store, {
serializer: serializer,
deserializer: deserializer
});
crosstabSync(persistor);
// this is exactly the same what redux-persist uses
function serializer(data) {
return JSON.stringify(data);
}
function deserializer(data) {
// this is the normal deserialization process
if (typeof data === 'string') {
return JSON.parse(data);
}
// basically we need to deserialize this one:
// var o = {
// f: '{"foo":"bar"}',
// b: '{"bar":"foo"}'
// };
return Object.keys(data).reduce(function(obj, key) {
obj[key] = JSON.parse(data[key]);
return obj;
}, {});
}
Or we could modify redux-persist-crosstab to support serialization/deserialization:
var constants = require('redux-persist/constants')
var keyPrefix = constants.keyPrefix
module.exports = function(persistor, config){
var config = config || {}
var blacklist = config.blacklist || false
var whitelist = config.whitelist || false
var serialize = config.serialize || function(data) {
return JSON.stringify(data)
}
var deserialize = config.deserialize || function(data) {
return JSON.parse(data)
}
window.addEventListener('storage', handleStorageEvent, false)
function handleStorageEvent(e){
if(e.key.indexOf(keyPrefix) === 0){
var keyspace = e.key.substr(keyPrefix.length)
if(whitelist && whitelist.indexOf(keyspace) === -1){ return }
if(blacklist && blacklist.indexOf(keyspace) !== -1){ return }
var statePartial = {}
statePartial[keyspace] = deserialize(e.newValue)
persistor.rehydrate(serialize(statePartial), function(){
//@TODO handle errors?
})
}
}
}
First one looks uglier but the latter one can hurt the performance :(
So probably the best would be having support in redux-persist for rehydrating serialized data.
I'm getting errors using this with
redux-persist
2.0 aspersistor.rehydrate
is being passed an object instead of a string, which causes the deserialise function to die. My workaround has been to parse the newValue value, then stringify the whole statePartial object:statePartial[keyspace] = JSON.parse(e.newValue); persistor.rehydrate(JSON.stringify(statePartial), function(){ //@TODO handle errors? })