purescript-optic-ui icon indicating copy to clipboard operation
purescript-optic-ui copied to clipboard

Composing calls to runhandler

Open FrigoEU opened this issue 10 years ago • 3 comments

Hey,

I've been using optic-ui for a small project and so far really liking it. I have a lot to learn in terms of how to build reusable components with all the facilities that both purescript and optic-ui offer, but one thing I keep running into is the fact that I can't do two runhandler invocations one after another.

I'm taking some cues from Elm by making a "handle" function that I pass down in the hierarchy and feed "commands" that then changes the state of a higher lying component. However I often want to do two things in response to an event: update the state of the current component AND call the handle function that got passed down. When I want to do it with simple do syntax like this:

do 
  runHandler h $ set _foo "bar"
  handle MyCommand

This doesn't work because of the gen counter in OpticUI.Run. I would make a PR if I had an idea how to fix this, but I don't... Any help much appreciated.

FrigoEU avatar Nov 07 '15 17:11 FrigoEU

Calling multiple handlers for the same state is problematic: Since there isn't really a viable way to have non-labelled stable paths into the state, a handler ultimately always carries implicitly a recipe how to reconstruct the entire application state when the state of a small component has changed. Basically a template where only the focused state is missing. If one were to call two handlers on the same state, even if the focused substates are morally independent, the second handler will revert the changes of the first.

This is unfortunate, of course, since - as you say - there are legitimate use cases for this: imagine a button component that takes an action to execute on click, but that also disables itself on click. If the action that has been passed to the button contains an invocation to a handler, the change of the state of the button will either revert the action of that handler (no gen counter) or will not occur at all (gen counter).

I currently don't have a clear idea how to solve this, but this and related issues are a pretty high priority to solve. Feel free to let me know of any ideas you might have, so we can work on a solution together.

zrho avatar Nov 18 '15 13:11 zrho

Have a look at d5e0cec9c9adce51d65e3c24442ff9e0a6f58568, especially the withEffects function and the effects example. This does not directly allow to compose handlers like in your example, but may allow to model your use-cases in a different manner. What do you think?

zrho avatar Jan 12 '16 15:01 zrho

I'll need to think about how my use case could be solved by this, but I definitely think it's a nice addition. I'm a little bit concerned with the ability to have hidden state like you showed in the effects example, but I guess it's up to the user to use this responsibly... Definitely think it's a nice addition, just need to figure out exactly what I can do with it :).

FrigoEU avatar Jan 18 '16 06:01 FrigoEU