07 — Shared state
Pass the { key } option to use() to share a signal across components. Same key in two places = same underlying signal. No Provider, no Context boilerplate.
tsx
import { use } from 'flexium/core'
function ThemeToggle() {
const [theme, setTheme] = use<'light' | 'dark'>('light', { key: 'theme' })
return (
<button onclick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>
Theme: {theme}
</button>
)
}
function StatusBar() {
// Same key — automatically subscribed to the same signal
const [theme] = use<'light' | 'dark'>('light', { key: 'theme' })
return <p>Current theme: {theme}</p>
}
function App() {
return (
<div>
<ThemeToggle />
<StatusBar />
</div>
)
}Clicking the button updates both components — the renderer only patches the affected text nodes.
Cleanup
When the last component using a key unmounts, the signal is released automatically (Phase 4's ComponentWeakRegistry + ref-counting). No memory leak.
To release manually (e.g., when logging out):
tsx
import { releaseGlobalKey } from 'flexium/core'
function logout() {
releaseGlobalKey('user')
releaseGlobalKey('theme')
// ...
}Key conventions
Keys are arbitrary strings. To avoid collisions in large apps, namespace them:
tsx
const [user] = use(null, { key: 'auth:user' })
const [token] = use(null, { key: 'auth:token' })
const [cart] = use([], { key: 'shop:cart' })Or use serializable arrays:
tsx
const [user] = use(null, { key: JSON.stringify(['user', userId]) })When to use Context vs { key } vs Stream
| Pattern | Use when |
|---|---|
use(value, { key }) | Globally shared signal; no Provider needed. Best for app-wide settings, auth, etc. |
Context | Tree-scoped value, multiple subtrees with different values (e.g., themed sections). |
Stream (flexism) | Server-pushed updates; subscribe across components, server is source of truth. |
API surface used
use(initial, { key })— keyed shared signalreleaseGlobalKey(key)— explicit cleanup (rarely needed)
Next
→ Canvas — declarative canvas rendering with <Canvas>.