I think I can finally explain Actions. Actions are functions that are called inside Transitions. It's similar to how events are functions called inside event handlers.
Comments
Log in with your Bluesky account to leave a comment
Actions work the same way, the function passed to startTransition is the action function, and callbacks are named with "action" to know it's called in an action context:
startTransition(
// this is the action
() => {
// this is the action callback
action();
}
)
By convention, callbacks in events are named with "on" or "handle". They look like event handlers, but they're not really, unless they're passed to the DOM node.
Callbacks called inside Actions are named with "action", but are not the action unless it's passed to startTransition.
The difference between event handlers and Actions is that Actions compose within a Transition. For events, you're tied to that one event scope, and if you do something async, they break out of that scope. Transitions can include multiple Actions across multiple events and async boundaries.
With event handlers, you need to manually manage multiple pending states across different events and async responses. With Actions, you can use a single pending state for the whole transition, and each Action will participate in the pending state.
This is useful whether the Action is sync or async, which means Actions are not just about async transitions (like I previously framed them, that's on me). They're really about the context of being inside a transition.
Yeah, that captures it. The only other caveat is that if the callback you pass calls `await` and sets state after, then you'll need to wrap the setState after in an additional startTransition to re-apply the action context (at least for now).
I mean, you're looking for an explanation that sticks here, so I thought it might help to give feedback how I perceived it, and not just the ones that comment "I understand".
But of course I can also just ignore it.
I'm more confused than before now anyways.
Mark gave me a different interpretation to read your comment so I probably read the wrong tone into it, sorry.
I think I generally get what "type of function" you want to describe with "event" (my connection to useEvent here was that it's the "type of fn" you'd have used with useEvent),
but my feedback would probably still be: I don't think most people will make that association. I think most people wouldn't call a function "event". Maybe a slightly different wording could help?
"similar to how events are functions" - I have never heard anyone call an onX function an "event". In my head an event is always a type that's dispatched by an emitter
Id call that a handler, input handler, or input value handler ie. A callback that handles a new value. The handler part is load bearing, I can't wrap my mind around calling that an event
ok replace my thread with "handler" where i say event. same idea - the term is overloaded but it's not confusing. if it has 'on' or 'handle' in it, then you know it's a handler, whether it's an event handler or a handler called inside an event handler doesn't matter.
Comments
// this is the event handler
function handleClick(event) {
// this is an event callback
onClick(event.target.value);
}
the handler is passed to the event, and callbacks inside are named like a handler, but are not really
startTransition(
// this is the action
() => {
// this is the action callback
action();
}
)
Callbacks called inside Actions are named with "action", but are not the action unless it's passed to startTransition.
If I'm making a component and I expose `saveAction={() => {...}`, is it fair say that it means:
1) Whatever callback you pass in here will be run inside of a transition
2) It can be sync or async
Any other rules I should follow?
Additional transition is what allows the setState to get entangled/batched into the wrapping transition from the component?
Re-apply action context is nice wording.
And how would you explain Transitions?
https://bsky.app/profile/phry.dev/post/3lcdmibi7x22k
But of course I can also just ignore it.
I'm more confused than before now anyways.
I think I generally get what "type of function" you want to describe with "event" (my connection to useEvent here was that it's the "type of fn" you'd have used with useEvent),
function Input({onChange}) {
function handleChange(event) {
onChange(event.target.value);
}
return (
defaultValue=""
onChange={handleChange)
/>
);
}
// Parent
{...}} />
what do you call the onChange the parent passes?