Filament.Hooks
(filament v0.2.1)
Copy Markdown
Hooks for Filament components.
Application-facing hooks
Call these at the top level of render/1:
use_state/1— local mutable state; returns{value, setter}use_observable/1— resolves a server reference to a pid (or nil when disconnected)use_observable/2— resolves a server and projects its state; fn receives:disconnectedwhen unavailableuse_effect/2— side-effect with optional cleanupmemo_at/3andevent_at/2— invoked by compiler-generated code from~Ftemplates
Pattern: use_observable/1 + use_observable/2
Resolve the server once with /1, then project from it with /2. This lets you pass
the server pid to child components and apply multiple projections from the same process:
def render(%{session_id: session_id}) do
server = use_observable(fn -> MyServer.start_link(session_id) end)
count = use_observable(server, fn
:disconnected -> 0
state -> state.count
end)
label = use_observable(server, fn
:disconnected -> ""
state -> state.label
end)
...
endPassing the server as a prop lets child components project their own values without creating redundant subscriptions:
<ChildComponent server={server} />
# In the child:
def render(%{server: server}) do
value = use_observable(server, fn
:disconnected -> nil
s -> s.some_field
end)
...
endRules of hooks
- Only call hooks at the top level of
render/1— not insideif,case, or comprehensions. - Hooks must be called during a render pass (a
RenderContextmust be active). - Hook identity is determined by call order (slot index). Conditional hooks corrupt state.
Summary
Functions
Schedules a side effect to run after the render completes.
Resolves an observable server reference to a pid, without subscribing.
Resolve an observable server and project its state into a value.
Returns the current state value and a setter function.
Functions
Schedules a side effect to run after the render completes.
effect_fn is called after the component renders. It may return a cleanup function (zero-arity fn returning :ok or any term) that is called:
- Before the next time the effect runs (when deps change), OR
- When the fiber unmounts
deps controls when the effect re-runs:
- [] — run once on mount, cleanup on unmount
- [dep1, dep2] — run when any dep changes (Kernel.== comparison), cleanup before re-run
- :always — run on every render
Rules: call only at the top level of render/1.
@spec use_observable( server_or_fn :: GenServer.server() | (-> pid() | {:ok, pid()} | GenServer.server()) ) :: pid() | GenServer.server() | nil
Resolves an observable server reference to a pid, without subscribing.
The argument can be any of:
- a pid, atom,
{:via, ...}, or{node, name}— used directly as the server - a zero-arity function — called on first connect (and again if the process dies) to
obtain a pid or
{:ok, pid}; useful when the component owns the server's lifecycle
Returns nil during disconnected (HTTP static) mounts. On subsequent renders,
reuses an existing pid if still alive; restarts a factory fn otherwise.
Use this hook when you want to pass the server identity to child components or
apply multiple projections from the same server via use_observable/2.
Must be called at the top level of render/1 in consistent order (like all hooks).
@spec use_observable( server_or_fn :: GenServer.server() | (-> pid() | {:ok, pid()} | GenServer.server()), project :: (term() | :disconnected -> term()) ) :: term()
Resolve an observable server and project its state into a value.
The first argument is a server reference (same as use_observable/1). The second
argument is a projection function called on every state update from the server. When
the server is unavailable (disconnected HTTP mount or nil), the function is called
with the atom :disconnected so it can return a safe default:
count = use_observable(CartServer, fn
:disconnected -> 0
state -> state.count
end)Passing the server as a prop lets a parent resolve the process once and share it with children that each apply their own projection:
# Parent
server = use_observable(fn -> MyServer.start_link([]) end)
<Child server={server} />
# Child
value = use_observable(server, fn
:disconnected -> nil
s -> s.some_field
end)Must be called at the top level of render/1 in consistent order (like all hooks).
Do not call inside conditionals or loops.
Returns the current state value and a setter function.
On the first render of this fiber, returns {initial, setter}. On subsequent renders, returns the most recently set value (or initial if never changed).
The setter is a closure. Call it from event handlers or effects to trigger a re-render. Calling the setter sends a message to the owning LiveView process, which re-renders the affected fiber.
Rules: call only at the top level of render/1. Do not call inside conditionals.