LiveView
Modern web applications usually render views in the browser using JavaScript. LiveView renders HTML on the server and pushes changes to the client through diffs over WebSockets.
A Counter
defmodule App1Web.CounterLive do
use Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok, assign(socket, :count, 0)}
end
def handle_event("increment", _, socket) do
{:noreply, update(socket, :count, &(&1 + 1))}
end
def render(assigns) do
~H"""
<div>
<p>Count: { @count }</p>
<button phx-click="increment">+</button>
</div>
"""
end
end
Add a routing rule under scope "/":
live "/counter", CounterLive
The counter is now ready at http://localhost:4000/counter.
Anatomy of a LiveView Component
The LiveView component is a module with specific functions like
mount, render and handle_event. Similar to React's class
component, those are called lifecycle callbacks, as they are invoked
at different stages.
-
mount: Invoked once when the component is first added to the page or the LiveView process is started. It's used to initialize the component's state (assigns). -
handle_event: Handles events originating from the client (e.g., button clicks). -
render: Called to generate HTML. -
update: Called whenever the assigns passed to the component from its parent LiveView change. It's an opportune place to update the component's internal state based on the new assigns.
A Rough Comparation with React
Life Cycle Callbacks:
| LiveView Component | React Class Component |
|---|---|
| mount(params, session, socket) | componentDidMount() |
| handle_event(event, params, socket) | custom functions |
| render(assigns) | render() |
| update(assigns, socket) | componentDidUpdate(prevProps, prevState) |
Event Handling:
| LiveView Component | React Class Component |
|---|---|
| phx-click | onClick |
| phx-change | onChange |
State Management:
| LiveView Component | React Class Component |
|---|---|
| assign(socket, state) | this.setState(state) |
| update(socket, key, fn) | this.setState(fn) |
Thoughts on LiveView
The ultimate goal of LiveView is to create dynamic server-rendered applications without writing JavaScript.
It is kind of a unique and intereting solution from Phoenix.
- States are kept on the server, not in the browser, rendering is also done on the server.
- After rendering, a diff with previous rendering result is done and only the diff is sent to the browser, in order to minimize the payload.
Why is the idea not adapted in other frameworks?
- It relies on WebSocket, which is cheap in Phoenix but a luxury for a lot of other frameworks.
- It's a back-end oriented solution, the JavaScript community is front-end centric, and LiveView solves a problem that they don't have.
LiveView is a good fit for
- Chats, monitoring(real-time updates)
- Dashboards, admin panels(limited number of concurrent users, relative simple interaction)
- Developers with limited front-end skills
Not suitable for
- UI-heavy apps with complex states
- Apps with extreme high-concurrency usage
- Mobile-first apps on unstable networks, or apps with offline usage