I just watched the wonderful video by Chris McCord about how to write a Twitter Clone with Phoenix LiveView within 15min (https://www.youtube.com/watch?v=MZvmYaFkNJI).
At around 11:45 he talks about how to update the struct rendered in a LiveComponent and he uses 3 mechanism to make this work. It is a bit unclear to me how Phoenix LiveView handles the updates under the hood and would much appreciate if somebody could explain it to me. So here are the mechanisms:
- Use the
update/3
function to prepend the updatedpost
to theposts
assigned to the socket.
{:noreply, update(socket, :posts, fn posts -> [post | posts] end)}
My question here is: How does Phoenix LiveView know which LiveComponent needs to be updated? I’m confused by the [post | posts]
part of the function since posts
is going to be an empty list after the initial render (see Mechanism 2). So, why is it necessary to prepend the post
to posts
?
- Set
posts
to betemporary_assigns
.
{:ok, assign(socket, :posts, fetch_posts()), temporary_assigns: [posts: []])}
To my understanding, this clears the assigned posts
from memory once the initial rendering has succeeded, after the LiveView is “hydrated” on the second render after the websocket connection is established.
- Set the posts DOM container to
phx-update="prepend"
<div id="posts" phx-update="prepend">
As I understand this code, LiveView is going to prepend any new posts to the list of LiveComponents, basically rendering any new posts at the top of the list of existing posts. But it is unclear to me how this interacts with the update(socket, :posts, fn posts -> [post | posts] end)
function. I would expect that an updated post is then rendered at the top of the list. So, we would end up having 2 rendered versions of the post, one original one and one with the updates.