Say I have a LiveView like so:
defmodule LvExampleWeb.PageLive do
use LvExampleWeb, :live_view
@impl true
def render(assigns) do
~H"""
<button phx-click="click">Update Name</button>
<p>Name: <%= @name %></p>
<p>Date: <span phx-hook="LocalDate" id="date"><%= @date %></span></p>
"""
end
@impl true
def mount(_params, _session, socket) do
{:ok,
socket
|> assign(name: "Foo")
|> assign(date: DateTime.utc_now())}
end
@impl true
def handle_event("click", _params, socket) do
{:noreply, assign(socket, :name, "Updated Foo")}
end
end
And a JS Hook LocalDate
let liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
hooks: {
LocalDate: {
mounted() {
let dt = new Date(this.el.textContent);
this.el.textContent = dt.toLocaleString();
},
},
},
});
When the live view is first loaded, the hook will run and update the text in timestamp format to localeFormat, example from 2022-06-06T15:48:10.636624Z
to 6/6/2022, 9:18:10 PM
.
Now when the Update Name
button is clicked and the name
assign is updated, the date also will revert to the timestamp format. (Loom recording).
I understand that this happens because the client has modified the DOM and the server isn’t aware of these changes. I know how to fix it as well.
My question is this: how does LiveView on the client know to change the date part as well? Does it keep a copy of the initial render in memory and apply the changes from the server on that copy and then update all the DOM nodes? Why doesn’t it apply the changes to the DOM directly?
Would love to understand this part better.
Thanks!