createEventDispatcherとは
createEventDispatcher
は、Svelteコンポーネントからカスタムイベントをディスパッチ(発行)するための関数です。これを使うことで、子コンポーネントが親コンポーネントにデータやイベントを通知することができます。
Svelte5でどう変わったのか
Svelte5では、createEventDispatcher
関数が非推奨となり、代わりにProps
としてコールバック関数を渡すようになりました。
また、 on:
ディレクティブが非推奨になっていますのでon:click
はonclick
のように単なるプロパティとしてイベントハンドラを指定するようになりました。
例をいくつか紹介します。
例1
Svelte4以前の書き方
[Demo]https://svelte.dev/playground/9553ad5a88c046c2a1d009e05894032c?version=4.2.19)
子コンポーネント
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
</script>
<button on:click={() => dispatch('notify', 'detail value')}>Fire Event</button>
親コンポーネント
<script>
import Child from './Child.svelte';
function callbackFunction(event) {
console.log(`Notify fired! Detail: ${event.detail}`);
}
</script>
<Child on:notify={callbackFunction} />
Svelte5で変わった書き方
子コンポーネント
<script>
let { onNotify } = $props();
</script>
<button onclick={() => onNotify('detail value')}>Fire Event</button>
親コンポーネント
<script>
import Child from './Child.svelte';
function handleNotify(detail) {
console.log(`Notify fired! Detail: ${detail}`);
}
</script>
<Child onNotify={handleNotify} />
例2
Svelte4以前の書き方
子コンポーネント
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function handleAdd() {
dispatch('add');
}
function handleSubtract() {
dispatch('subtract');
}
</script>
<button on:click={handleAdd}>Add</button>
<button on:click={handleSubtract}>Subtract</button>
親コンポーネント
<script>
import Child from './Child.svelte';
let number = 0;
function handleAdd() {
number++;
}
function handleSubtract() {
number--;
}
</script>
<Child on:add={handleAdd} on:subtract={handleSubtract} />
<p>Number: {number}</p>
Svelte5で変わった書き方
子コンポーネント
<script>
let { add, subtract } = $props();
</script>
<button onclick={add}>Add</button>
<button onclick={subtract}>Subtract</button>
親コンポーネント
<script>
import Child from "./Child.svelte"
let number = $state(0);
</script>
<Child add={() => number++} subtract={() => number--} />
<p>Number: {number}</p>
例3
Svelte4以前の書き方
子コンポーネント
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
let power = 5;
</script>
<button on:click={() => dispatch('inflate', power)}>
inflate
</button>
<button on:click={() => dispatch('deflate', power)}>
deflate
</button>
<button on:click={() => power--}>-</button>
Pump power: {power}
<button on:click={() => power++}>+</button>
親コンポーネント
<script>
import Child from './Child.svelte';
let size = 15;
let burst = false;
function reset() {
size = 15;
burst = false;
}
</script>
<Child
on:inflate={(power) => {
size += power.detail;
if (size > 75) burst = true;
}}
on:deflate={(power) => {
if (size > 0) size -= power.detail;
}}
/>
{#if burst}
<button on:click={reset}>new balloon</button>
<span class="boom">💥</span>
{:else}
<span class="balloon" style="scale: {0.01 * size}">
🎈
</span>
{/if}
<style>
span {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 100vh;
text-align: center;
line-height: 1;
pointer-events: none;
}
.balloon {
transition: scale 0.2s;
}
.boom {
animation: boom 0.5s forwards;
}
@keyframes boom {
0% {scale: 0.6}
25% {scale: 0.75}
100% {scale: 0}
}
</style>
Svelte5で変わった書き方
子コンポーネント
<script>
let { inflate, deflate } = $props();
let power = $state(5);
</script>
<button onclick={() => inflate(power)}>
inflate
</button>
<button onclick={() => deflate(power)}>
deflate
</button>
<button onclick={() => power--}>-</button>
Pump power: {power}
<button onclick={() => power++}>+</button>
親コンポーネント
<script>
import Child from './Child.svelte';
let size = $state(15);
let burst = $state(false);
function reset() {
size = 15;
burst = false;
}
</script>
<Child
inflate={(power) => {
size += power;
if (size > 75) burst = true;
}}
deflate={(power) => {
if (size > 0) size -= power;
}}
/>
{#if burst}
<button onclick={reset}>new balloon</button>
<span class="boom">💥</span>
{:else}
<span class="balloon" style="scale: {0.01 * size}">
🎈
</span>
{/if}
<style>
span {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 100vh;
text-align: center;
line-height: 1;
pointer-events: none;
}
.balloon {
transition: scale 0.2s;
}
.boom {
animation: boom 0.5s forwards;
}
@keyframes boom {
0% {scale: 0.6}
25% {scale: 0.75}
100% {scale: 0}
}
</style>
さいごに
Svelte5でcreateEventDispatcher
関数が非推奨になったことにより、createEventDispatcher
周りのボイラープレートが削減されたり、学習コストが減りました。
propsになったことでどういうイベントを必要としているのかが明確になり、処理が追いやすくなったと思います。