9.11. SolidJS Integration¶
Wire a ComponentVMOf<M> to a Solid component via createSignal and
createEffect — Solid's fine-grained reactivity primitives.
9.11.1. Reactivity primitive¶
createSignal(initial)returns a[get, set]pair. Reads are tracked inside JSX and reactive scopes; writes trigger re-renders for any subscriber.createEffect(fn)runsfnon every change to signals it reads.onCleanup(fn)registers teardown.
9.11.2. Mapping¶
| Solid | VMx |
|---|---|
createSignal(x) set |
PropertyChangedMessage<T> handler |
onClick={() => fn()} |
command.execute() in fn |
createMemo(() => ...) |
DerivedProperty<T> / fromSources |
onCleanup(() => cleanup) |
dispose the subscription |
9.11.3. Adapter skeleton¶
import { createSignal, onCleanup, type Accessor } from "solid-js";
import { filter } from "rxjs/operators";
import {
ComponentVMOf,
type ICommand,
type IMessageHub,
PropertyChangedMessage,
} from "@thekaveh/vmx";
export function useVm<M, K extends keyof ComponentVMOf<M>>(
vm: ComponentVMOf<M>,
hub: IMessageHub,
property: K
): Accessor<ComponentVMOf<M>[K]> {
const [value, setValue] = createSignal(vm[property]);
const sub = hub.messages
.pipe(filter((m): m is PropertyChangedMessage<unknown> =>
m instanceof PropertyChangedMessage &&
m.sender === vm &&
m.propertyName === property))
.subscribe(() => setValue(() => vm[property]));
onCleanup(() => sub.unsubscribe());
return value;
}
export function NoteView(props: {
vm: ComponentVMOf<Note>;
hub: IMessageHub;
saveCommand: ICommand;
}) {
const model = useVm(props.vm, props.hub, "model");
return (
<>
<h1>{model().title}</h1>
<button onClick={() => props.saveCommand.execute()}>Save</button>
</>
);
}
9.11.4. Fuller example¶
No worked Solid Notes-Showcase ships yet. The React recipe (react.md) shares the same hub-subscription shape.