Overview

useStore(store) registers the current host for re-render whenever store notifies. It accepts anything with __subscribe (Mates atoms, setters, actions) or subscribe (Zustand, Redux, custom).

It returns the same store for chaining. Cleanup is automatic on unmount. Prefer reading Mates atoms inside the template when you only need Mates reactivity — use useStore to bridge external stores or to opt a host into updates without relying solely on template tracking.

vs template atom reads

Approach
Deps
Prefer when
count() in template auto-track Default for Mates atoms inside the rendering component.
useStore(store) manual host sub Third-party stores, or ensure a host re-renders on notify.

Subscribe to a shared atom

Display and App both call useStore(shared) so they stay subscribed to the module-level atom.

import { html, atom, x, useStore, renderApp } from 'mates';

const shared = atom(0);

const Display = () => {
useStore(shared);
return () => html`
<div class="card card-body p-10 center">
<h1>${shared()}</h1>
</div>
`;
};

const App = () => {
useStore(shared);
return () => html`
<div class="m-col m-gap">
${x(Display)}
<button class="btn-primary" @click=${() => shared.set(n => n + 1)}>+1</button>
</div>
`;
};
renderApp(App, document.getElementById('app'));

External subscribe()-shaped store

useStore works with Redux/Zustand-style { subscribe }. The playground uses a tiny custom store with the same shape.

import { html, useStore, renderApp } from 'mates';

// Minimal store shaped like Zustand / Redux (subscribe, not __subscribe)
function createExternal(initial) {
let value = initial;
const listeners = new Set();
return {
getState: () => value,
setState: (next) => {
value = typeof next === 'function' ? next(value) : next;
listeners.forEach((l) => l());
},
subscribe: (l) => { listeners.add(l); return () => listeners.delete(l); },
};
}

const ext = createExternal(0);

const App = () => {
// Host re-renders when ext.subscribe fires — even though getState is not an atom
useStore(ext);
return () => html`
<div class="m-col m-gap">
<h1>${ext.getState()}</h1>
<p class="muted m-t-5">external store via subscribe()</p>
<button class="btn-primary" @click=${() => ext.setState(n => n + 1)}>+1</button>
</div>
`;
};
renderApp(App, document.getElementById('app'));