You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As promised from this discussion, here is a proposal to implement helper function(s) that implement the following preventable events pattern.
Stateful vs stateless components
The problem is always state. Whether or not to make components that are stateful or stateless is always a big debate. React's paradigm says always be stateless, but components are meant to encapsulate predictable functionality, so the more of that the component can provide, the less code needs be in consuming devs apps.
@calebdwilliams and I have come up with an idea/pattern for preventable events that enable a component to default to a stateful implementation, but allow the dev to selectively prevent an event and thereby also prevent any stateful code that would have run as a result of that event being emitted. Closing a modal is a simple example, though there are plenty of others, particularly with inputs which are by nature stateful in HTML.
Sure, you could build a modal component that only open/closed with a boolean attribute on the tag. Making a completely stateless component gives the consuming dev the ability to decide when the modal window should close, BUT one drawback of a completely stateless component is that the dev MUST ALWAYS make it close, even in simple case where the modal should just close when the close button is clicked and not do anything special.
In those cases, forcing the developer to add the document.querySelector(modalSelector).open = false; is a bit of unnecessary code that preventable events could....prevent.
Consider a modal component like:
classModalextendsLit{
@property()open;privateemitCloseModal(){constevent=newCustomEvent('modal-closed',{detail: true});this.dispatchEvent(event);if(!event.defaultPrevented){this.open=false;// only close the modal window automatically if the close event hasn't been defaultPrevented.}}render(){returnhtml` ...stuff<buttonclass="close-modal" @click="emitCloseModal">X</button> ...stuff `;}
Considering this example, since event handlers are executed syncronously, the emitCloseModal method won't continue until all event handlers are completed. At that point, it's possible to check to see if the event was canceled anywhere in the handler chain (presumably by devs looking to perform their own logic).
If the developer doesnt prevent the event, then the modal closes itself automatically and the developer doesnt need to attach any application state to the modal state to sync them up. The modal can manage its own simple state, still be opened again with the open prop. But its one less piece of code the dev has to write.
If the developer wants to do some validation before the modal is closed, THEN close it after success, without the preventable event pattern, the developer wouldnt be able to control that functionality AND have a stateful component that automatically closes itself when the button is clicked.
With preventable events, all the developer has to do is
// <x-modal @modal-closed="handleClose()">handleClose(event){event.preventDefault();// now the modal will not close itself automatically
... dologicstuffmyModalRefElement.open=false;// manually close the modal in a "stateless" way}
Sample implementation
A library helper function might be something similar to:
functionemitPreventableEvent(elementToBind: HTMLElement){returnfunction(eventName: string,eventPayload: EventDetail,eventOptions: EventInitPartial,callback: ()=>unknown){constdefaults={bubbles: true,cancelable: true};constactualOptions=Object.assign({},defaults,eventOptions)constevent=newCustomEvent(eventName,actualOptions);element.dispatchEvent(event);if(!event.defaultPrevented){cb.call(element);// call the callback bound to the host element so that the callback could use `this` correctly}};}
used in a LitElement component (or any component for that matter):
pretty simple in implementation i think (there are probably things that could be added), but a pretty powerful method of having a component be somewhat stateful for simplicity but still allowing selective developer control to "go stateless" when necessary/beneficial.
This approach would work really well for components that just have/manage simple state, but still need some way for the developer to "control" it some of the time but not always.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
As promised from this discussion, here is a proposal to implement helper function(s) that implement the following preventable events pattern.
Stateful vs stateless components
The problem is always state. Whether or not to make components that are stateful or stateless is always a big debate. React's paradigm says always be stateless, but components are meant to encapsulate predictable functionality, so the more of that the component can provide, the less code needs be in consuming devs apps.
@calebdwilliams and I have come up with an idea/pattern for preventable events that enable a component to default to a stateful implementation, but allow the dev to selectively prevent an event and thereby also prevent any stateful code that would have run as a result of that event being emitted. Closing a modal is a simple example, though there are plenty of others, particularly with inputs which are by nature stateful in HTML.
Sure, you could build a modal component that only open/closed with a boolean attribute on the tag. Making a completely stateless component gives the consuming dev the ability to decide when the modal window should close, BUT one drawback of a completely stateless component is that the dev MUST ALWAYS make it close, even in simple case where the modal should just close when the close button is clicked and not do anything special.
In those cases, forcing the developer to add the
document.querySelector(modalSelector).open = false;
is a bit of unnecessary code that preventable events could....prevent.Consider a modal component like:
Considering this example, since event handlers are executed syncronously, the
emitCloseModal
method won't continue until all event handlers are completed. At that point, it's possible to check to see if the event was canceled anywhere in the handler chain (presumably by devs looking to perform their own logic).If the developer doesnt prevent the event, then the modal closes itself automatically and the developer doesnt need to attach any application state to the modal state to sync them up. The modal can manage its own simple state, still be opened again with the
open
prop. But its one less piece of code the dev has to write.If the developer wants to do some validation before the modal is closed, THEN close it after success, without the preventable event pattern, the developer wouldnt be able to control that functionality AND have a stateful component that automatically closes itself when the button is clicked.
With preventable events, all the developer has to do is
Sample implementation
A library helper function might be something similar to:
used in a LitElement component (or any component for that matter):
pretty simple in implementation i think (there are probably things that could be added), but a pretty powerful method of having a component be somewhat stateful for simplicity but still allowing selective developer control to "go stateless" when necessary/beneficial.
This approach would work really well for components that just have/manage simple state, but still need some way for the developer to "control" it some of the time but not always.
Beta Was this translation helpful? Give feedback.
All reactions