Last active
January 14, 2023 21:18
-
-
Save motss/d89a5ccb056e42e6d283363c0a6a9f57 to your computer and use it in GitHub Desktop.
Best of both worlds: lit-element + mobx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { html, LitElement } from 'https://unpkg.com/lit-element@latest/lit-element.js?module'; | |
import { observable, action, autorun, reaction } from 'https://unpkg.com/mobx@latest/lib/mobx.es6.js?module'; | |
const store = observable({ | |
title: 'Hello, World!', | |
count: 0, | |
incrementCount: action(() => { | |
store.count += 1; | |
}), | |
}); | |
/** [DEBUG]: Inspect store values */ | |
autorun(() => { | |
console.log('store', { ...store }); | |
}); | |
class MyElement extends LitElement { | |
static get properties() { | |
return { | |
count: { type: Number }, | |
title: { type: String }, | |
}; | |
} | |
constructor() { | |
super(); | |
reaction( | |
() => [store.count, store.title], | |
([count, title]) => { | |
this.count = count; | |
this.title = title; | |
}, | |
{ fireImmediately: true } | |
); | |
} | |
render() { | |
return html` | |
<h1>${this.title}</h1> | |
<button @click="${this._incrementCount}">Click Me | ${this.count}</button> | |
`; | |
} | |
_incrementCount() { | |
store.incrementCount(); | |
} | |
} | |
window.customElements.define('my-element', MyElement); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { html, LitElement } from 'https://unpkg.com/lit-element@latest/lit-element.js?module'; | |
import { observable, action, autorun, reaction } from 'https://unpkg.com/mobx@latest/lib/mobx.es6.js?module'; | |
const version = 'test::v0::local_state'; | |
const lc = window.localStorage; | |
const savedState = lc.getItem(version); | |
const store = observable({ | |
title: 'Hello, World!', | |
count: 0, | |
incrementCount: action(() => { | |
store.count += 1; | |
}), | |
...JSON.parse(savedState), | |
}); | |
/** [DEBUG]: Log latest states and save states in localStorage */ | |
autorun(() => { | |
const states = { ...store }; | |
const toBeSaved = Object.keys(states).reduce((p, n) => { | |
const val = states[n]; | |
if ('function' === typeof(val)) return p; | |
p[n] = val; | |
return p; | |
}, {}); | |
console.log('store', toBeSaved, lc.getItem(version)); | |
lc.setItem(version, JSON.stringify(toBeSaved)); | |
}); | |
class MyElement extends LitElement { | |
static get properties() { | |
return { | |
count: { type: Number }, | |
title: { type: String }, | |
}; | |
} | |
constructor() { | |
super(); | |
reaction( | |
() => [store.count, store.title], | |
([count, title]) => { | |
this.count = count; | |
this.title = title; | |
}, | |
{ fireImmediately: true } | |
); | |
} | |
render() { | |
return html` | |
<h1>${this.title}</h1> | |
<button @click="${this._incrementCount}">Click Me | ${this.count}</button> | |
`; | |
} | |
_incrementCount() { | |
store.incrementCount(); | |
} | |
} | |
window.customElements.define('my-element', MyElement); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { html, LitElement } from 'https://unpkg.com/lit-element@latest/lit-element.js?module'; | |
import { observable, action, autorun, reaction } from 'https://unpkg.com/mobx@latest/lib/mobx.es6.js?module'; | |
const store = observable({ | |
title: 'Hello, World!', | |
count: 0, | |
updateTitle(title) { | |
this.title = title; | |
}, | |
incrementCount() { | |
console.log('ic'); | |
this.count += 1; | |
}, | |
resetCount() { | |
console.log('rc'); | |
this.count = 0; | |
} | |
}); | |
const mobxify = superclass => { | |
return class extends superclass { | |
connectedCallback() { | |
super.connectedCallback(); | |
autorun(() => this.storeUpdated()); | |
} | |
storeUpdated() {} | |
}; | |
}; | |
class MyElement extends mobxify(LitElement) { | |
storeUpdated() { | |
this.title = store.title; | |
this.count = store.count; | |
this.requestUpdate(); | |
} | |
render() { | |
return html` | |
<h1>${this.title}</h1> | |
<button @click="${this._click}"> | |
<span>Current count is ${this.count}</span> | |
</button> | |
<button @click="${this._reset}">Reset count</button> | |
<button @click="${this._updateTitle}">Update title</button> | |
`; | |
} | |
_click() { | |
store.incrementCount(); | |
} | |
_reset() { | |
store.resetCount(); | |
} | |
_updateTitle() { | |
const rng = Math.random(); | |
const randTitle = Math.floor(rng * 2) ? rng.toString(16).slice(-7) : 'Hello, World!'; | |
store.updateTitle(randTitle); | |
} | |
} | |
window.customElements.define('my-element', MyElement); | |
class MyElement2 extends mobxify(LitElement) { | |
storeUpdated() { | |
this.title = store.title; | |
this.requestUpdate(); | |
} | |
render() { | |
console.log('myelement2::render'); | |
return html` | |
<h1>${this.title}</h1> | |
`; | |
} | |
} | |
window.customElements.define('my-element2', MyElement2); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo link: https://jsbin.com/ligujajayu/edit?html,output
Demo with
storeUpdated
method: https://jsbin.com/qemetucizo/edit?html,output