@smith.adriane, I’m exploring membrane and it looks really cool and full of potential! I was wondering about how state can be stored when using the functions in membrane.component
. make-app
seems to allow vars and atoms as the container for state. Could it also be an agent? Agents might be a better choice if the state also has to interact with for example the filesystem.
Or am I not understanding how state is handled in membrane.component
?
make-app
is really only meant to work with atoms
you could still use an agent if you wanted, but you would need to write your own version of make-app
the issue I see with agents is that they're asynchronous, so if you process an event from the mouse or keyboard, it's indeterminate as to when the updated state will be reflected
maybe I don't fully understand the use case
That’s a good point. I’m wondering how to handle saving some part of the application state to durable storage (e.g. a file). I always thought that changes to atoms could be potentially retried if there was some sort of conflict, so that the might not be the best solution if you wanted to interact with the filesystem in a watcher or something
there's a few different ways to handle that. you could write to storage as part of an effect, or you could add a watcher to the state atom with add-watch
I recently wrote a blog post about the design of membrane.component
, https://blog.phronemophobic.com/reusable-ui-components.html
I'll probably post it #news-and-articles and the clojure subreddit on Monday
Thanks! I’ll read that 🙂
Let me know if anything is confusing. Would love to hear your feedback 🙂
@smith.adriane your article is clear and really helps understand what is going on. I’m not totally there yet however. I guess the part I’m having trouble putting together is how this would al combine with a durable backend such as database or a filesystem. But maybe you haven’t written that article yet 😉
To me it seems a good idea to make sure the ui-state resides in atoms and such. I can imagine a flow something like this: user <--> ui (state in atoms) <--> db <--> outside world (that is also affecting the db)
. But I’m not yet seeing how I would connect it all together. For example: if the user expresses intent, resulting in some effect that references some entity in an atom, how can I also translate that intent to some underlying durable database? Should effects use both references and identifiers?
@jlmr, All good questions. How you persist your data will depend on the use case. A couple approaches come to mind:
• put all state in an atom, use add-watch
to periodically flush state to durable storage
• put all state in a db, all effects update the db and the ui queries the db (with caching) when it needs to re-render.
• hybrid approach. some data is stored in a db, some state is stored in an atom. the necessary state from each is combined to re-render the UI.
> Should effects use both references and identifiers?
Identifiers are references. The three main techniques are nesting, identifiers, and stateful references. For data stored in a database, using identifiers might be the most straightforward approach.
I know that doesn't really answer your question, but I think the right answer will depend on your use case. I'm happy to provide more clarification or examples if you have a specific use case in mind.