-
-
Save projektorius96/26c51fbd88655de46227e635280ea28d to your computer and use it in GitHub Desktop.
useEffect() for `LitElement`... because everyone's doing it?
This file contains 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 {LitElement, html} from '@polymer/lit-element'; | |
import {UseEffectMixin} from './use-effect.js'; | |
class MyElement extends UseEffectMixin(LitElement) { | |
static get properties() { | |
return { | |
mood: {type: String}, | |
expression: {type: String} | |
} | |
} | |
constructor() { | |
super(); | |
// useEffect() with set up and cleanup. | |
this.useEffect((props) => { | |
let {mood} = props; | |
console.log('effect', mood); | |
return () => { | |
console.log('cleanup', mood); | |
} | |
}); | |
// useEffect() with a property change gate | |
this.useEffect(() => console.log(this.mood), ['expression']); | |
// useEffect() for firstUpdated() and disconnectedCallback() | |
this.useEffect(() => { | |
console.log('first'); | |
return () => console.log('last'); | |
}, []); | |
} | |
render() { | |
return html` | |
<style> .mood { color: green; } </style> | |
A ${this.expression} sort of ${this.mood}. | |
`; | |
} | |
} |
This file contains 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
const hasRecentlyConnected = Symbol(); | |
const effects = Symbol(); | |
const cleanups = Symbol(); | |
const cleanupsDisconnected = Symbol(); | |
const cleanup = Symbol(); | |
const UseEffectMixin = (base) => { | |
return class extends base { | |
[effects] = []; | |
[cleanups] = []; | |
[cleanupsDisconnected] = []; | |
connectedCallback() { | |
this[hasRecentlyConnected] = true; | |
super.connectedCallback(); | |
} | |
disconnectedCallback() { | |
super.disconnectedCallback(); | |
this[cleanups] = this[cleanup](this[cleanups]); | |
this[cleanupsDisconnected] = this[cleanup](this[cleanupsDisconnected]); | |
} | |
updated(changedProperties) { | |
super.updated(changedProperties); | |
this[cleanups] = this[cleanup](this[cleanups]); | |
this[effects].map(({effect, tests}) => { | |
if (tests && ((!tests.length && !this[hasRecentlyConnected]) || !tests.every(test => changedProperties.has(test)))) return; | |
const cleanup = effect(this); | |
if (cleanup && (!tests || tests.length)) this[cleanups].push(cleanup); | |
else if (cleanup) this[cleanupsDisconnected].push(cleanup); | |
}); | |
this[hasRecentlyConnected] = false; | |
} | |
[cleanup](cleanups) { | |
cleanups.map(cleanup => cleanup()); | |
return []; | |
} | |
useEffect(effect, tests) { | |
this[effects].push({effect, tests}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment