Svelte: Event forwarding with dispatcher vs passing in handling function, which is best practice?

…衆ロ難τιáo~ 提交于 2021-02-07 20:23:29

问题


Let's say an Outer component contains an Inner component, and we want an event from the Inner component to be propagated to the Outer component. Without using the store, there are 2 ways to do this:

Method 1: Event forwarding using dispatcher

Inner.svelte: Use Svelte's dispatcher to dispatch a repackaged version of the original event:

<input type="text" on:input={callDispatcher} />

const dispatcher = createEventDispatcher();

function callDispatcher(e) {
    dispatcher("mymsg", {
        foo: e.target.value
    });
}

Outer.svelte: Listen for Inner's dispatched event:

<Inner on:mymsg={handler} />

function handler(e) {
    alert(e.detail.foo);
}

Method 2: Pass Outer's handler directly to Inner

Inner.svelte: Accepts handler passed in by Outer:

export let externalHandler;
<input type="text" on:input={externalHandler} />

Outer.svelte: When Inner event of interest occurs, it will call Outer's handler:

<Inner externalHandler={handler} />

function handler(e) {
    alert(e.target.value);
}

Question

Which one is a better practice? Method 1's dispatcher seems to be an unnecessary middle-layer that not only adds more code but also loses the original event information. But strangely, the Svelte tutorial mentions Method 1 instead of Method 2.


回答1:


There is no real difference and you can indeed use both. However, method 2 will not work for native elements, leaving you with a mix of both approaches and you get cod like this:

<Child clickHandler="{childClick}" />
<button on:click="{buttonClick}">click</button>

You would always have to remember when to use which one, while if you use the dispatcher method this will always be the same

<Child on:click="{childClick}" />
<button on:click="{buttonClick}">click</button>

The extra dispatcher code is a trade-off in this.




回答2:


Adding a link to Why use createEventDispatcher? (Svelte GitHub Issue) comment that covers this nicely, imho:

By using createEventDispatcher, you are telling the compiler to compile your component in such a way that any events it emits adheres to the typical CustomEvent interface. This isn't that big of a deal if you are just dealing with Svelte, but I gather that if you are compiling Svelte components to be used elsewhere as web components, your compiled component will be compiled with an interface other frameworks will understand (…).

This makes sense.

Earlier in the thread:

It's now (Mar 2019) a lot easier to have props that are callbacks in Svelte 3, so you'll probably be using events less anyway.

That suggests there might be some evolutionary reason for the two to co-exist.

One more thing: with events, one is tied to the Custom event interface and the .detail wrapping (that's the whole point!). That may seem like additional complexity to the outer component, whereas with function references one can craft a more slender API.

If one ends up doing function references, notice the <Thing1 {onClick} /> shorthand in the linked issue.


Edit: It doesn't seem that simple. Events are not emitted from components ... (opened Jun 2019) shows that Svelte events aren't fully usable in web components. Until that's resolved, dispatching likely falls in between two worlds. Not really standard. Not really custom.




回答3:


I find using function prop much simpler, more idiomatic, and does the job elegantly most of the time for me.

<!-- App.svelte -->
<Button onClick={handleClick}></Button>

<!-- Button.svelte -->
<button on:click={onClick}>
  Click me
</button>

The only case I use event forwarding is when I need to do... well... event forwarding. :) (from deeply nested component)

<!-- App.svelte -->
<Outer on:customEvent={handleCustomEvent} />

<!-- Outer.svelte -->
<Inner on:customEvent />

<!-- Inner.svelte -->
<Button on:customEvent />

<!-- Button.svelte -->
<button on:click={() => dispatch('customEvent')}>
  Click me
</button>

Reference: https://www.donielsmith.com/blog/2020-04-21-props-vs-event-dispatcher-svelte-3/

Disclaimer: I'm new to Svelte, coming from React. 🥳



来源:https://stackoverflow.com/questions/61569655/svelte-event-forwarding-with-dispatcher-vs-passing-in-handling-function-which

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!