-
-
Save du5rte/dbd18a1a6dc72d866737a5e95ca1e663 to your computer and use it in GitHub Desktop.
import mobx from "mobx" | |
import store from "store" | |
export default function(_this) { | |
let firstRun = true | |
// will run on change | |
mobx.autorun(() => { | |
// on load check if there's an existing store on localStorage and extend the store | |
if (firstRun) { | |
const existingStore = store.get("store") | |
if (existingStore) { | |
mobx.extendObservable(_this, existingStore) | |
} | |
} | |
// from then on serialize and save to localStorage | |
store.set("store", mobx.toJS(_this)) | |
}) | |
firstRun = false | |
} |
import mobx, { computed, observable } from "mobx" | |
import autoSave from "./autoSave" | |
const initialTodoStore = { | |
todos: ["buy milk", "buy eggs"] | |
} | |
class TodoStore { | |
constructor() { | |
// set initial mock up examples | |
this.todos = initialTodoStore // or [] | |
// in the future it will over run it and save to store | |
autoSave(this) | |
} | |
@observable todos | |
@observable filter = "" | |
@computed get filteredTodos() { | |
const filter = new RegExp(this.filter, "i") | |
return this.todos.filter(todo => !this.filter || filter.test(todo)) | |
} | |
} | |
const todoStore = window.todoStore = new TodoStore | |
export default todoStore |
Hi there
I'm trying to read read/write in store but from differents browser tabs:
URL for tab1: /mydomain
URL for tab2: /mydomain/test
I'm trying to figure out how to set reaction to listen changes in localstorage. The flow will be like this:
tab1 set var visible in store to true, then tab2 listen the change (from localstorage I suppose) and show something into tab2.
Is it possible to do that? Any idea how to do it?
thanks in advance.
@hartum websockets maybe? idk why you wanna persist such data in localstorage but i guess hmr in react/next works like that only. they use websockets to listen if ui in one browser changed & update it everywhere i guess :)
Using websockets seems to me a bit drastic solution. The reason is two browser windows/tabs of the same SPA, because the client wants to open several instances of components and be able to use it on several monitors.
In case anyone is interested what I did to solve my problem was to use the 'mobx-persist-store' library to write my store data to the localStorage.
Then (inside my store) I added a store event listener and update it every time I detect a change.
in mobxStore.ts
import { makePersistable, hydrateStore } from 'mobx-persist-store';
class Store {
// --- STORE STATE VARS ---
dashboard = {
isVisible: true,
};
constructor() {
makePersistable(this, { name: 'mobxStore',
properties: ['dashboard'],
storage: window.localStorage }).finally(() => {});
}
// --- SHOW/HIDE DASHBOARD ---
setDashboard(visible: boolean) {
this.dashboard.isVisible = visible;
}
}
const myStore = new Store();
window.addEventListener('storage', (e) => {
if (e.key === 'mobxStore') {
myStore.hydrateStore().catch(() => {});
}
});
export default myStore;
in a different window (but same domain http://localhost:3000/test )the component:
import React from 'react';
import { observer } from 'mobx-react';
import store from 'store/mobxStore';
const FakeComponent = () => {
const visible = store.dashboard.isVisible;
return (
<div>
{store.dashboard.isVisible ? <span>Dashboard visible</span> : <span>Dashboard Invisible</span>}
<br />
<div onClick={() => store.setDashboard(!visible)} >"Switch dashboard visibility"</div>
</div>
);
};
export default observer(FakeComponent);
@dizys nice one. Currently, I use mobx-persist-store as it's a library plus battle-tested with edge-cases. Works with TypeScript as well 🎉