Tonic web components with signals for state sync
Published on 21 January 2023
I‘ve been looking into Tonic, a tiny web-components wrapper. Combining it with preact core signals to add state synchronisation is just a few lines:
export class Component extends Tonic { _set(...args) { effect(() => { super._set(...args) }) } }
Adding an optimised ${value} wrapper that only rerenders the changed value is another extension on the Component class:
... html(strings, ...values) { const modifiedValues = values; values.forEach((value, index) => { if (value instanceof Signal) { modifiedValues[index] = super.html`<signal-wrapper signal=${value}></signal-wrapper>`; } }) return super.html(strings, ...modifiedValues); } ...
And then define the <signal-wrapper> component that gets injected in places where signal is passed without .value reads:
class SignalWrapper extends Tonic { // don’t render initially, FIXME: do I need it? preventRenderOnReconnect = true render() { return this.html`${this.props.signal.value}`; } connected() { this.unsubscribe = effect(() => { this.props.signal.value; this.reRender(); }) } disconnected() { this.unsubscribe(); } }