I often imagine state and events as the two impulses that drive an application. I like React a lot, but a common pitfall is that it is 95% focused on state, and so you get odd cases where you end up trying to encode events as state.
You’ll see this anywhere you see a usePrevious-like hook that you then use to determine if something changed and act on it (eg. I hold state that a robot is offline, but I want to do something special when a robot goes offline). This is inferring an event from state.
I’ve had luck adding an event bus as a core driver of a complex react application for events I don’t want to track as state. But it always feels that it’s a bit in conflict with the state-driven nature of the application.
Why is this so weirdly prescriptive about inline event handlers?
> Even in a single file, inline event handlers are not a good idea. One button is OK, but what if you had 100 buttons? You'd have to add 100 attributes to the file; it would quickly turn into a maintenance nightmare.
> You should never use the HTML event handler attributes — those are outdated, and using them is bad practice.
It’s a really good explanatory text, and then get surprisingly opinionated.
Similarly, why is an online event handler considered a security risk? I just don’t see the difference between that and using a named function?
Using Svelte and building global state classes with $state(), $effect() has really helped with managing side-effects and surgical updates without building a custom event system which has historically added unnecessary boilerplate to many of my projects with a frontend.
Having components bound to or using any of the $states or $derived update automatically without having to manually register event listeners, firing events, etc.
Used to dislike runes so much initially, but working a bit more deeply with them has really made me appreciate the API changes.
You can think of any software (or hardware) as a state that transitions to a new state when an event happens.
State0 -event0-> State1 -event1-> State2 etc.
In other words, it's all a state machine.
Protip: Make your web SDK APIs EventTargets instead of creating custom event subscription models wherever practical.
I dropped all state except local state in react and replaced it with events.
Driving UI declaratively via prop changes sounds great in theory but it’s actually a nightmare. Better to use events, dramatically simplifies things.
I think events are a bit unsung and underutilized in a lot of web projects. Events are really powerful and you can build systems with them that can replace proprietary framework features with interoperable protocols.
Context: Components that need a context value can fire an event to request it. Any other element or listener higher in the tree can handle the event and provide a value via the event object. Event are synchronous, so you can get values synchronously. The Web Components Community Group maintains an interoperable context community protocol: https://github.com/webcomponents-cg/community-protocols/blob...
Suspense: Components that have some pending some work, like awaiting data to render, can fire an event to signal that they have pending work. The event can carry a promise, and then a suspense-boundary-like component can handle the event and display a spinner until all the pending work in the tree below it is finished. Another protocol: https://github.com/webcomponents-cg/community-protocols/blob...
Error boundaries: A component can fire an ErrorEvent if it fails to render, and an error boundary component can display the error or some other user affordance.
Child-parent registration: A child component can fire an event to tell some parent that it's available. This is useful for using components as plugins. A <code-mirror> element could have children that provide language support, syntax highlight themes, etc.
Actions: Redux-like actions can be done with events instead. You can build a nice data-down, events-up system this way with very little code and very loose coupling.
Event buses: components can listen for events on a top-level node like document, and they'll receive every event of that type from every other dispatcher.