LiveViewReact supports programmatic events, server-pushed events, Phoenix JS
callback props, and normal phx-* bindings rendered by React.
Programmatic events
const { pushEvent } = useLiveViewReact();
const reply = await pushEvent<{ count: number }>("increment", { by: 1 });See Client hooks for subscriptions, reply state, connection state, and navigation.
Phoenix JS callback props
Declare a callback with a lowercase kebab-case r-on:* attribute:
<.react
id="counter"
component="Counter"
socket={@socket}
r-on:increment={
JS.transition("opacity-50", to: "#status")
|> JS.push("increment",
target: "#counter-component",
loading: "#status",
value: %{source: "server"}
)
}
/>The attribute becomes an onCamelCase React prop:
type CounterProps = {
readonly onIncrement: (payload?: {
readonly by: number;
}) => void;
};
function Counter({ onIncrement }: CounterProps) {
return (
<button type="button" onClick={() => onIncrement({ by: 2 })}>
Increment
</button>
);
}The value must be a Phoenix.LiveView.JS command or nil. An ordinary prop
with the generated callback name is an error. Callback metadata is transported
separately from ordinary props and is validated during live rendering, SSR,
and hydration.
The optional callback payload must be a plain JSON object. For every JS.push
in the command chain, payload fields override fields with the same names in
the static value: option. Other transition, target, loading, DOM, and
navigation commands remain in their original order. Inputs and commands are
copied rather than mutated.
Unchanged command chains retain the same function reference. Replaced, removed, or destroyed callbacks become inert, including references retained outside the React tree. Invoking a callback during SSR or hydration throws a clear error; callbacks become live after hydration commits.
phx-* inside React DOM
Phoenix LiveView delegates its DOM events, so lowercase bindings rendered by React work directly:
<button type="button" phx-click="increment" phx-value-by="1">
Increment
</button>The packaged runtime includes the React JSX augmentation for phx-*
attributes. No wrapper component is required. Phoenix remains responsible for
event targeting, loading classes, and reconnect behavior.