Skip to content

Auto-dispatch #9060

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

Closed
ethanlal04 opened this issue Jul 31, 2023 · 2 comments
Closed

Auto-dispatch #9060

ethanlal04 opened this issue Jul 31, 2023 · 2 comments

Comments

@ethanlal04
Copy link

Describe the problem

I really love Svelte and think its awesome. But like anything else in life, its not perfect.

One of the things I totally hate is the amount of boilerplate you need to dispatch a simple event.

Just look at this:

<script>
  import { createEventDispatcher } from 'svelte';
  
  const dispatch = createEventDispatcher();

  function dispatchSay(text) {
    dispatch('say', text);
  }
</script>

<button on:click={() => dispatchSay('Hi')}>
  Say 'Hi'
</button>

Hellfire, right?

React has a much simpler way to do this, i.e. no way. People just carry in event handlers like props and call them as needed inside the child component. Its simple and needs zero lines of code. But, having actual DOM-like events can be powerful as it lets you access the event object, which you can't in handler prop functions. Also, it makes it similar to handling regular events raised by DOM elements which we are all familiar with.

Describe the proposed solution

To get the best out of both worlds, I came up with this syntax:

<script>
  export function say() {}
</script>

<button on:click={() => say('Hi')}>
  Say 'Hi'
</button>

How cool is that? Here, the function say() is the dispatcher. Calling it dispatches the event say, named after itself.

I think this syntax is perfect cuz

  1. It's just 1 line of code.
  2. It's totally valid JS.
  3. The syntax (outside of context="module") currently doesn't seem to do anything than declare a function say(). Idk, I played with it a bit.
  4. It's similar to the style Svelte deals with props and thus consistent.

From the perspective of the parent component, this should look the same as a manually dispatched event.

<script>
  import Inner from './Inner.svelte';

  function handleSay(event) {
    alert(event.detail.text);
  }
</script>

<Button on:say={handleSay} />

The body part of export function say() {} though, having no role in the dispatch, yet being there, kinda bugged me. After some thought, I realized that it can hold the default behaviour of the event just like that in a regular DOM event. Funnily, it's similar to setting the default value of a prop. Anyway, I think this can turn out quite powerful. To do so, we can optionally take in the detail parameter (renamed to whatever) inside the dispatcher and do something useful with it like this:

export function say(text) {
  // Do something useful by default
}

Don't want this functionality?
Just leave the body empty and no need to accept the 'text' parameter!

As for createEventDispatcher(), I'm not saying we should get rid of or deprecate it. It can sit around, doing no harm, to not break any existing code. Maybe, auto-dispatch (as I call this thing) can be syntactic sugar over manually creating dispatchers, just like auto-subscription is for manually handling store subscriptions.

I think this would be a fine addition to Svelte. Thoughts?

Alternatives considered

None.

Importance

would make my life easier

@gtm-nayan
Copy link
Contributor

Duplicate of #5602

@gtm-nayan gtm-nayan marked this as a duplicate of #5602 Jul 31, 2023
@gtm-nayan gtm-nayan closed this as not planned Won't fix, can't repro, duplicate, stale Jul 31, 2023
@Conduitry
Copy link
Member

Exporting a function in the <script> block does do something currently - it creates a method on the component instance. We shouldn't hijack that and switch it (in some cases) to be related to event emitting. I'd probably be in favor of closing #5602 as well.

There's also already #3488 for reducing the boilerplate with emitting events in other ways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants