@dojo-ng/store
v0.1.1
Published
Dojo NG external-store controller for Lit components
Readme
@dojo-ng/store
Connects Lit components to an external store, so a component re-renders when the state it uses changes.
Part of Dojo NG, a framework-agnostic web component library. BSD-3-Clause.
Install
npm install @dojo-ng/storeUsage
Create a store, then select the value a component uses.
import { LitElement, html } from "lit";
import { createStore, StoreController } from "@dojo-ng/store";
export const counter = createStore((set) => ({
count: 0,
increment: () => set((s) => ({ count: s.count + 1 })),
}));
class CountButton extends LitElement {
// Re-renders only when `count` changes.
#count = new StoreController(this, counter, (s) => s.count);
render() {
return html`<button @click=${() => counter.getState().increment()}>
Clicked ${this.#count.value} times
</button>`;
}
}
customElements.define("count-button", CountButton);What is in the package
StoreController: a Lit reactive controller. Pass a store and a selector. The host re-renders only when the selected value changes (compared withObject.is).createStore: re-exported from Zustand's vanilla build, for an app that does not have a store yet.ReadableStore: the type the controller needs. Any object withgetState()andsubscribe(listener)works, so you can use Zustand, Valtio, Nano Stores (with a small adapter), or your own store.
Observable interop
- These helpers are for apps that already use RxJS or another library that follows the
Symbol.observableprotocol. Nothing in this package needs RxJS. toObservable(store): an observable that emits the current state at once, then every change.fromObservable(input, initial): aReadableStorethat follows an observable.initialis required, because an observable has no current value until it emits.ObservableController: re-renders the host on every value from an observable.
Examples
Bridge to RxJS
Turn an observable into a store, or a store into an observable.
import { from, interval } from "rxjs";
import { fromObservable, toObservable } from "@dojo-ng/store";
import { counter } from "./counter.js";
// An observable as a store. Use it with StoreController or the context registry.
const ticks = fromObservable(interval(1000), 0);
ticks.getState(); // 0 until the first tick
// A store as an observable. Use it with RxJS operators.
from(toObservable(counter)).subscribe((state) => console.log(state.count));