Problem
You are building a website for listening to your favorite songs. You want to play or pause the current song while you are adding songs to your playlist or even editing your profile. You create a LiveView to handle the player controls and show the status of the current song… but something unexpected is happening: every time you navigate around different LiveViews, the LiveView for the player controls loses the current song state. Notice how the play progress bar flickers? It’s being remounted!
Why is this happening?
The nested LiveView for the player controls loses its state and is recreated every time a live_redirect
happens to the parent
LiveView. The live_redirects
happen when the user navigates.
Can we avoid recreating our nested LiveView between live redirects?
Solution
LiveView 0.17.6
added the sticky option for the live_render/3
function. The sticky
option means a LiveView can remain active across live redirects within our application. Even if it is nested within another LiveView!
This means a few things:
- the song player LiveView doesn’t get re-rendered with each
live_redirect
- the player keeps its state (no expensive re-building the internal state)
- the life-cycle of the LiveView is not affected
How do we use this new option? It is really easy:
<%= live_render(@socket,
LiveBeatsWeb.PlayerLive,
id: "player",
session: %{},
sticky: true) %>
Passing the sticky: true
option, LiveView does the necessary magic to keep our PlayerLive
LiveView even in case of live redirects.
Let’s see it in action!
Our player no longer renders over and over again!
Discussion
LiveView is maturing nicely. Refinements like the sticky option are evidence of that. This is a nice feature to know about when working with nested LiveViews. It means a child LiveView doesn’t lose its state and get remounted when a live_redirect
happens in the parent. This means you can create more advanced applications with a better user experience and still get all the productivity benefits of LiveView!