Phoenix LiveView
02 / 02

Phoenix LiveView: PubSub, Components & Hooks

Phoenix LiveView: PubSub, Components & Hooks

Reacting to Events From Other Sources

def mount(_params, _session, socket) do
  Phoenix.PubSub.subscribe(MyApp.PubSub, "orders")
  {:ok, socket}
end

def handle_info({:new_order, order}, socket) do
  {:noreply, update(socket, :orders, &[order | &1])}
end

# handle_info/2 reacts to broadcasts from OTHER users or
# background jobs -- not just this user's own phx-click events

Stateful live_component

defmodule MyAppWeb.SearchBoxComponent do
  use MyAppWeb, :live_component

  def handle_event("search", %{"query" => q}, socket) do
    {:noreply, assign(socket, :results, MyApp.search(q))}
  end
end

# In a parent LiveView's template:
# <.live_component module={SearchBoxComponent} id="search" />

JS Commands: No Round-Trip Needed

<button phx-click={JS.toggle(to: "#menu")}>Menu</button>

# Simple visual effects (toggling a class, a transition) run
# instantly client-side -- no server round-trip needed for this

Hooks: Integrating Custom JavaScript

A phx-hook attaches custom JavaScript that runs at defined lifecycle points (mounted, updated, destroyed) for a specific element -- the escape hatch for integrating third-party JS libraries (a chart, a map) that need direct DOM access LiveView doesn't natively provide.

The Trade-off: A Live Connection Is Required

Because state and logic live on the server, most interactivity requires the WebSocket connection to be active. LiveView's client JS auto-reconnects on drops, but this is a real trade-off against an SPA that can keep functioning longer on cached client-side state.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free