There are two popular approaches to propagate events between two components in Svelte. In this post, we will look at Svelte Props vs Event Dispatcher.

The first approach uses callback functions. The other uses event dispatcher. Svelte supports both. However, one might be more suitable than the other in particular situations.

1 – Using Callback Functions as Props

The first approach is to use callback functions as Props. This is a common method in frameworks such as React.

Essentially, we pass the action from one component to another by using props.

For example, we have a reusable button component as below:

<script>
    export let buttonClicked = () => alert("I'm the default greeting")
</script>
<button on:click={buttonClicked}>
    Greet
</button>

We can now use this button in another component.

<script>
     import ReusableButton from './ReusableButton.svelte';
</script>
<ReusableButton buttonClicked={() => alert("I'm the customized greeting")}/>

Here, we pass the callback function buttonClicked() as a prop to the ReusableButton component. When the button is clicked, the callback function is triggered.

However, if we don’t pass the callback function, the default message will be displayed. See below case:

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

In this case, the click handler within the component is triggered.

2 – Using Svelte Event Dispatcher

Svelte provides an in-built event dispatcher. You can read in detail about event dispatcher in this post. In a nutshell, the event dispatcher allows us to fire custom events.

Let’s see it in action.

Below is the refactored version of the ReusableButton component.

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

    export let buttonClicked = () => dispatch("customEventButtonClicked")
</script>
<button on:click={buttonClicked}>
    Greet
</button>

Here, we use the dispatch() function to create a custom event with name customEventButtonClicked. This name could be anything we want.

We can now listen to this event in our main component.

<script>
     import ReusableButton from './ReusableButton.svelte';
</script>
<ReusableButton on:customEventButtonClicked={() => alert('I am a custom greeting event')}/>

As you can see, we are using the on: directive. The event name is customEventButtonClicked. This is same as the name of the custom event.

In the above example, we trigger an inline function that displays an alert. However, we can also keep propagating the event by not defining any action. So, even if you have a hierarchy of components, the event will keep moving up as long as the on:customEventButtonClicked is present.

3 – Svelte Props vs Event Dispatcher

Should you use Svelte Props or Event Dispatcher?

As with most things in life, the answer is not black and white. Both the approaches have their pros and cons.

PropsEvent Dispatcher
Props support implementation of default behaviourEvent dispatcher does not have default behaviour
Using props for a chain of components is cumbersome due to prop drillingWith event dispatcher, we only need to have the on: directive. No need to worry about passing the props
No additional code neededWe need to import an additional function and create custom events

Usually, for a simple use case such as passing an event handler one component down, props are a better choice. You don’t need to work with the createEventDispatcher.

However, if we are passing a callback function through a chain of components, things can get cumbersome. In such cases, it might be a better choice to use the event dispatcher.

Conclusion

In this Svelte Props vs Event Dispatcher discussion, we looked at both approaches with examples. Also, we tried to understand the pros and cons of both the options and which one you can choose depending on your requirement.

Hope this post was useful.

If you have any comments or queries, please feel free to mention them in the comments section below.

Categories: Svelte

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *