State Management with Phoenix LiveView

Recently, I completed a first product with Phoenix LiveView and ran into the classical problem that it became unclear how, when and from where the State of the UI was changing. Facebook tackled this problem by developing the Flux pattern, which was adopted by every major SPA Framework out there (e.g. Redux, Vuex, Ng-Redux). I took the time to write an example Framework/Module that tries to replicate the Flux pattern inspired by how Vuex was implemented. I created an Example repository here. The core logic can be found here. Your opinion on the usefulness of such a library and comments/improvement suggestions on the implementation are most appreciated :slight_smile:

11 Likes

Hello,

I think that MUTATIONS mutate, shouldn’t be used in your code because they are terms associated with graphql(absinthe) ecosystem and a lot of people will get confused.

It may even have conflicts.

I hope you found this info useful.

Good luck with your project…

1 Like

Thanks @wolfiton, however the naming convention is given by the Vuex flux flow. Unless somebody uses these 2 libraries side-to-side, I don’t expect the naming will be confusing though since the application contexts are quite different.

So, 2 major things happened since I started this thread:

  1. I finished a first implementation of LiveEx - a state management library for Phoenix LiveView. Please check it out and comment, recommend, contribute to it :slight_smile:

  2. I wrote on Medium about how to use the library. Hopefully, this article clears up what the flux pattern is, why it might be important for LiveView, and how to use the LiveEx dependency.


Also, some other cool things happened:

  1. Chris McCord pointed out the assign_new/3 function to share parent state with child LiveViews. I will look further into this function and will check out how to use it in LiveEx.

  2. Guido Tripaliresponded to my Medium article and suggested to bring the discussion about how to manage state to this forum.


I would like to pick up Guidos suggestion and start a discussion about what you think about how state can be managed best between nested LiveViews. A couple of questions to start with:

  1. Have you run into issues already where state changes became unclear? If yes, how did you solve this?
  2. Do you think that a flux based state management like implemented in LiveEx will be useful?
  3. Do you think state management should be baked into the Phoenix LiveView library or should third-party libraries offer that functionality instead?

I’m curious about your answers :slight_smile:

8 Likes

IMO state management should (eventually) be baked into LiveView itself. With React, navigating the many flavors of 3rd party Flux libraries has been a productivity killer.

4 Likes

just to give out a sign of life! After commenting your article on Medium I’ve start writing my thoughts about the status handling, but I realised that it will take me much more time to elaborate a satisfactory analysis to share with all of you here, because the matter have complex structure and maybe can be useful to have a sort of ontology of which are the actions, the events and the states involved in a typical full Phoenix app.

1 Like

Very cool library. I’ll be following the development.

1 Like

I agree with you. At least a certain combination like React/Redux should become a standard so that the decision making effort is mitigated.

1 Like

Looking forward to your findings :slight_smile:

1 Like

Thanks! Feel free to test it and potentially contribute :slight_smile:

2 Likes

Does current implementation assume that there is a single root LiveView for the whole app, and all routes are implemented via child live views? :thinking: I mean, if I want a global state shared between all live views.

For now there is a one-to-one mapping between a store and a root LiveView, and if I have something like live "/one", OneLiveView; live "/two", TwoLiveView, live views One* & Two* will get different stores and state will not be shared between them, right?

Also, in the readme I found a notion of feature/integrate-genserver branch, which seems capable to share state between live views, but I haven’t found the branch itself, has it been removed for some reason?

Yes and no. The intent of the library is to share state within one stack of LiveViews. So, one parent with children LiveViews. You make a very good point, that the actual intent should be to share state between all different LiveViews! That’s at least how e.g. vuex etc. work. If I have time, I will look into that, but PRs are always much appreciated :slight_smile:

Yes, right now, they would get different stores. You’re right, that should change however. I haven’t thought about that.

I attempted to use GenServer to keep the state in its own process next to the root LiveView process. However, I decided on keeping the state within the root LiveView process instead since if the root LiveView process goes down, there’s no LiveView that could still use the state anyway since all child LiveViews die as well.
However, using GenServer would be a great solution for state management between all LiveViews, not only the individual stacks of LiveViews. This should be the way forward indeed.

3 Likes

If you want to keep the state, then this a good case for https://hexdocs.pm/elixir/Agent.html

1 Like

Also, don’t get me wrong - I’m far from being sure that store actually should share state between views. I’m new to Elixir and Phoenix, and I can’t even imagine all potential implications of such move. I just was searching for something like a shared state, and hoped you had already found & solved all of them.

For example, as I understand, for now every LiveView is run in a separate process and so if we have 100K users connected, we have 100K processes with isolated states - 1 process per user. But if we put everything into a single store, we’d get states of those 100K users consolidated in a single process. I’ve no idea if that bad, but it seems going against LiveView design (and probably Elixir itself).

1 Like

I would love a flux-style state management thing for LiveView. However, before tackling that, isn’t the bigger problem the RAM usage on the server? Seems like that’s the main technical issue faced by LiveView atm.

1 Like

Can you elaborate a little bit, is there a place I can read about the issue or check it out by myself? :thinking:

1 Like

This guy explains it well:

1 Like

That’s interesting. Is there a more deep discussion about that somewhere? Or that guy is really the first one noticing an elephant in the room? Also, doesn’t hibernation address that in some way?

1 Like

Chris Mccord answered his tweet on hackernews

5 Likes

I updated the library to work with LiveView 0.15.7 and implemented some comments from @Maxim-Filimonov . Please let me know if you have any feature requests or similar recommendations and I’m happy to extend this library :heart:

1 Like