phoenixframework / phoenix_live_view

Rich, real-time user experiences with server-rendered HTML
https://hex.pm/packages/phoenix_live_view
MIT License
6.14k stars 921 forks source link

keep stream items on rejoin #3353

Closed SteffenDE closed 2 months ago

SteffenDE commented 2 months ago

This ensures JS commands are properly re-applied when a LV reconnects.

Originally reported in Slack (https://elixir-lang.slack.com/archives/CD594E0UU/p1721248736382849):

I'm having a heck of a time converting a UI pattern from React to LiveView, which is inline edit of content within a list view, ideally using LiveView streams. I also want to ensure that only one row can be edited at a time. I was able to get all of this working wonderfully using JS commands to add/remove classes, but anytime the user loses connection (mobile device or a server deployment) and reconnects, the stream ends up re-rendering and we lose which item user was editing which is not a great UX.

If I don't use streams, the JS command changes seem to persist across reconnects, but updating a single row when something updates is more difficult (plus I don't want it all in memory).

Is there a recommended way to do this with LiveView? I've tried updating the URL when clicking "edit", but there's a noticeable delay when on a mobile device.

Would having a hook to store the editing row be helpful, and then sending that info back to the server on socket reconnect? I've read that hooks and restore shouldn't really be used for UI state.

While it is often preferable to store important state somewhere more durable (for example in case of accidental page refreshes), the different behavior of stream and non-stream items wasn't deliberate, so this PR fixes that.