Fundamentals
Modifying state with events
Read time: 3 minutes
#Welcome to the dynamic world
In a modern front-end framework you don't want a view that shows something and is never modified again. We will learn the first way to modify state in LiveView: events.
We're going to build a simple button that reverses the current user's name. Create an events.exs
file with the following code:
Mix.install([
{:liveview_playground, "~> 0.1.1"}
])
defmodule PageLive do
use LiveviewPlaygroundWeb, :live_view
def mount(_params, _session, socket) do
socket = assign(socket, name: "Lubien")
{:ok, socket}
end
def render(assigns) do
~H"""
<div>
Hello <%= @name %>
<input type="button" value="Reverse" >
</div>
"""
end
end
LiveviewPlayground.start()
We don't have anything that different to our previous code here except the button. So far just basic HTML. Let's do some magic now. Edit the input and add a handle_event
as in the code below:
defmodule PageLive do
use LiveviewPlaygroundWeb, :live_view
def mount(_params, _session, socket) do
socket = assign(socket, name: "Lubien")
{:ok, socket}
end
def render(assigns) do
~H"""
<div>
Hello <%= @name %>
<input type="button" value="Reverse" phx-click="reverse" >
</div>
"""
end
def handle_event("reverse", _params, socket) do
socket = assign(socket, name: String.reverse(socket.assigns.name))
{:noreply, socket}
end
end
With this small modification we see the first example of reactivity in Phoenix: phx-click
. When clicked, this input generates an event for your LiveView with the name you chose, in this case "reverse"
. Run the server one more time and see that when you click the button, your name is reverted!
#How do they work?
Let's talk about handle_event/3
. This function is a callback that is only necessary if your LiveView has an event. For each event in your HTML code you need a corresponding def handle_event("your_event", _params, socket)
. The three arguments that this callback receives are, respectively:
Reminder about callbacks!
- The name of the event you defined.
- Event parameters (we will explore more in another lesson, at the moment we are just ignoring this argument).
- The state of the Socket for the current user.
Just like the mount/3
callback you receive the socket
so you can modify it however you want. The expected return of the function is {:noreply, socket}
.
:ok
or :noreply
?
mount/3
we respond with {:ok, socket}
while in handle_event/3
we use {:noreply, socket}
. The
mount/3
is just a function that LiveView executes while it's preparing its view, so it follows the Elixir pattern of saying "everything is OK, here's the initial socket". Now
handle_event/3
internally uses an Erlang/Elixir standard called GenServer
("Generic Server") and in the future we will see that we can also return a value for the element that generated the event with {:reply, map(), socket}
!
#Recap!
-
By adding
phx-click="event_name"
to an element you trigger an event name"event_name"
when it is clicked. -
For each event in your HTML you need an equivalent
handle_event("event_name", _params, socket)
callback. -
The
mount/3
callback returns{:ok, socket}
while thehandle_event/3
returns{:noreply, socket}
.
Feedback
Got any feedback about this page? Let us know!