-
-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Why use createEventDispatcher? #2323
Comments
I'm actually not sure - I was about to answer with the standard answer for several questions related to this (that runtime imports from function createEventDispatcher() {
const component = current_component;
return (type, detail) => {
const callbacks = component.$$.callbacks[type];
if (callbacks) {
// TODO are there situations where events could be dispatched
// in a server (non-DOM) environment?
const event = custom_event(type, detail);
callbacks.slice().forEach(fn => {
fn.call(component, event);
});
}
};
} But it feels like we should be able to just directly use |
Maybe we should be — I'm not aware how EDIT: Please ignore the following, I thought the implementation had callbacks, but it's actually all the same call stack. Obsolete considerations insideIt looks like it's bound to What I mean is this (note the code comments): // If we replaced all `component` with `current_component`...
function dispatch(type, detail) {
// ...are we guaranteed to have the same `current_component` here...
const callbacks = current_component.$$.callbacks[type];
if (callbacks) {
const event = custom_event(type, detail);
callbacks.slice().forEach(fn => {
// ...and here?
fn.call(current_component, event);
});
}
}; This looks like it would be an issue. However, regarding the "standard answer": Is there an FAQ where this is written down, maybe with the reasoning why Svelte does touch a lot of stuff, but not this? 🙂 |
Exports in |
Alright, that sounds reasonable. And I think my first considerations were actually correct: import { dispatch } from 'svelte';
function sayHello() {
// `current_component` might have changed by the time this is called
dispatch('message', {
text: 'Hello!'
});
} It still feels a little bit off though to use rather verbose constructs like |
However, this definitely clarified my question, thanks for taking care. 🙂 |
Yeah, you're right, it doesn't work. As for the terseness: It's now a lot easier to have props that are callbacks in Svelte 3, so you'll probably be using events less anyway. Having to create a dispatcher is a little verbose, yeah, but it does seem necessary given other goals and constraints. |
Related: when would you recommend using |
@JohnnyFun I had the same question today, and have come up with what I hope is an answer. Hopefully someone can correct me if I am not quite right or missing something important. By using If you aren't doing anything tricky like that, then the main benefit I see is easily letting the event of a child component be exposed from a parent. In your example, if you wanted to wrap
Now,
Also, since these are DOM events, you can also use modifiers, such as:
From what I can tell, you can get away with passing methods through props. There are some small benefits to using the dispatcher, but it would be pretty much mandatory if you are doing something where your svelte components are used in a system besides Svelte. |
Sure, I could see that being the explanation. Sounds like there are ways to pass function refs to web component instances, but I suppose people would also want to have a more common interface for their web components' events. Fwiw, you could do Also fwiw, I think |
Coincidentally today, I've created a // dispatch.js
import { createEventDispatcher } from 'svelte'
export const dispatch = {
subscribe(fn) {
fn(createEventDispatcher())
return () => {}
}
} <script>
import { dispatch } from './dispatch'
function foo() {
$dispatch('bar')
}
</script> https://svelte.dev/repl/ae1e9514c42845a4b3d30bb3af1168e4?version=3.44.2 |
@bluwy wahoo! |
what about unsubscribe? |
unsubscribe is a no-op function since there's nothing to unsubscribe to. We're using Svelte's auto-subscription feature to call the |
Because you might need data inside data inside data that is so far into an obscure part of an app that it isn't as simple as a quick, on:click do a thing in the other thing. I've got a component that display or hides other components based on the variables within components that may or may not have been clicked in other components... it sounds like a ClusterF$&K but createEventDispatcher made it a breeze. |
Curious... do you still use this? Found any issues? Seems like such a clever approach! @bluwy |
Yep, it still works great 👍 |
I'm currently going through the v3 tutorial and I'm a little bit confused by the use of
createEventDispatcher()
to emit events:From reading the Svelte source, I'm aware that calling this function returns a dispatcher bound to that very component.
However, this feels weirdly verbose for how brief Svelte usually is. Is there a reason we can't (or shouldn't) just do this...
...and let the compiler do the actual binding (e.g. directly after importing
dispatch
to the component)?The text was updated successfully, but these errors were encountered: