Skip to content

Instantly share code, notes, and snippets.

@heyimalex
Last active May 1, 2020 09:17
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save heyimalex/0f5ee73e581f64b6c290 to your computer and use it in GitHub Desktop.
Save heyimalex/0f5ee73e581f64b6c290 to your computer and use it in GitHub Desktop.
localStorage sync with redux
import { reduxStorageReducer, ReduxStorage } from 'reduxStorage';
import myReducer from './myReducer';
function compose(...reducers) {
return (state, action) => {
return reducers.reduce((reducedState, reducer) => {
return reducer(reducedState, action);
}, state);
};
}
const finalReducer = compose(myReducer, reduxStorageReducer);
const storage = new ReduxStorage('redux');
const redux = createRedux(finalReducer, storage.load());
storage.connect(redux);
import WebStorage from 'WebStorage';
const STORAGE_SYNC = 'STORAGE_SYNC';
export const actions = { STORAGE_SYNC };
export function syncActionCreator(state) {
return {
type: STORAGE_SYNC,
synced: state,
};
}
export function reduxStorageReducer(state, action) {
if (action.type === STORAGE_SYNC) {
// Depends on state being an object|null|undefined
return Object.assign({}, state, action.synced);
} else {
return state;
}
}
export class ReduxStorage extends WebStorage {
connect(redux, actionCreator = syncActionCreator, listen = true) {
redux.subscribe(() => this.save(redux.getState()));
if (listen) {
this.listen(() => redux.dispatch(actionCreator(this.load())));
}
}
}
export default class WebStorage {
constructor(key, storageArea = window.localStorage) {
this.key = key;
this.storageArea = storageArea;
}
load(defaultValue) {
const serialized = this.storageArea.getItem(this.key);
return serialized === null ? defaultValue : this.deserialize(serialized);
}
save(data) {
if (data === undefined) {
this.storageArea.removeItem(this.key);
} else {
this.storageArea.setItem(this.key, this.serialize(data));
}
}
clear() {
this.storageArea.removeItem(this.key);
}
serialize(value) {
return JSON.stringify(value);
}
deserialize(value) {
return JSON.parse(value);
}
listen(callback) {
const handler = (e) => {
if (e.key === this.key && e.storageArea === this.storageArea) {
callback(e);
}
};
window.addEventListener('storage', handler);
return () => window.removeEventListener('storage', handler);
}
}
@awendland
Copy link

In WebStorage.js, the serialize method is misspelled as serialze. (Just an FYI for people copy-pasting)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment