-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling multiple states in event handlers #39
Comments
I've run into the same problem lately and I've been trying to fix this in the |
Thanks for such a fast response. I will take a look at the 0.11 branch. Is there anything that was specifically changed in that branch to deal with this issue that I should focus on first? Since there really is only one parent for each child, and in order to execute the call back you need the parents React context which is already parameterized by the parent's state and props, I was thinking of maybe adding a new Effect type which would contain the callback event and would be type checked against the parents prop and state for safety. That way the callback action can be encapsulated into its own type safe Effect and would no longer interfere with the typed EventHandlerContext of the child. Maybe that is nonsense though because at some point the new Effect would need to be turned into an EventHandlerContext of its own and I'm not sure how that would work. |
Nothing specifically changed really, but that branch is a pretty big overhaul of the general architecture, and it got me thinking about composition again, which naturally leads to this issue when the user is given direct access to the state update function (without using the old I think Thermite doesn't really need to concern itself with the effects from the I think the key though is that there are two sets of state and action types: the ones at the top level that the component will be embedded in, passed to |
Yes, I checked it out and it is a pretty significant revision. My previous approach had been drawn from the React docs on facebook's github page, which tend to treat the child components as basically pure rendering functions from the parent, with the parameters being passes as |
@born2defy I've simplified the code in the 0.11 branch so that the React effects aren't even used any more (safe because the user doesn't get access to React's |
Hi Phil, I was actually looking over the code last night when the new commit came in, and I definitely appreciate the simplification of the effects. I was playing around with the |
I'm not sure I fully understand the use case you'd like to support. Could you write down some type signatures of what you'd like the components to look like please? |
I guess essentially what I am trying to do is create some components which have an opaque internal For example, imagine a component called
When the user tabs out of the input, the event handler is run and the input text is validated. If it succeeds a The parent component might have an action type which has a constructor designed to handle child updates, like this:
I am struggling to figure out how we could make a |
Why not use the module system with smart constructors to only export the bits of state and actions that you want? Another option might be to use |
In the most recent version of the 0.11 branch, how would you combine the parent and child specs into a single spec with |
Using smart constructors sounds interesting, but I'm not exactly sure how that would look in practice. Would it be possible to provide a simple example? |
I can, but probably after I finish off work on the
So something like type ParentState = Tuple A B
type ChildState = Tuple A C where only In that case, I'd hide the data constructor for hide :: Spec eff (Tuple state hidden) props action -> Spec eff state props action to hide a piece of state, since |
Interesting. I am eager to see where this branch ends up. |
I am new to Purescript and Thermite, so please pardon me if the answer to this question is obvious. I would like to define a child component which has its own state and event handlers which it uses to validate its input. For example, take a simple text input. When we receive the onChange event from the DOM, we call our custom component action which validates the input and then updates its internal state accordingly (re-rendering itself to display a validation error). When the value is determined to be valid, I want the child component to call an event handler that it received from a parent component through its props. This way the valid value can then be passed back to the parent which can handle it accordingly.
However I am running into issues due to React's EventHandlerContext and Thermite's Action monad both being parameterized by component state.
Currently I can call the parent event handler function directly from the DOM event in the rendered child component (using React.Dom.Props.onChange), and since that function expects any kind of EventHandlerContext this works fine. However, if I want to run the child event handler first to validate the input, I get a type error since the parameterized state for each of the EventHandlerContext operations are different (child state vs parent state). So I can call the parent's event handler with the value, but I can't validate the value in the child component first.
If I choose to handle the onChange event usingThermite's PerformAction with a custom Action type in the child component, I can validate the input but I am unable to call the parent's event handler function for the same reason - the 2 states are different and so the two Thermite.Action operations have different state types. So in this case I can validate the value in the child but am unable to pass it to the parent's event handler.
Is there some way to accomplish both? I would like to encapsulate some simple validation into dumb child components so I can re-use them with different parent components. The parent does not need to worry about validation - it simply gets a valid input event or it gets no event at all, and the child handles all the validation with the user. Is there a simple way to accomplish this that I am overlooking?
The text was updated successfully, but these errors were encountered: