【ITニュース解説】Svelte Event Forwarding & Advanced Component Patterns

2025年09月06日に「Dev.to」が公開したITニュース「Svelte Event Forwarding & Advanced Component Patterns」について初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

ITニュース概要

Svelteのイベントフォワーディングは、子コンポーネントで発生したイベントを親コンポーネントに伝える仕組み。再利用可能なコンポーネント作成に役立つ。Propsで親から子へイベントハンドラを渡し、子でイベント発生時に親のハンドラを実行。イベントをフォワーディングしないと、親はイベントを認識できない。制御されたコンポーネントと非制御コンポーネントの使い分けも重要。

ITニュース解説

Svelteにおけるイベントフォワーディングとコンポーネントパターンについて解説する。

Svelteで再利用可能なコンポーネントを作成する際、イベントフォワーディングは非常に重要なテクニックだ。これは、コンポーネントが受け取ったイベントを親コンポーネントに伝達する仕組みを指す。

まずは基本的なボタンコンポーネントから見てみよう。Button.svelteというファイルを作成し、<button>要素を配置する。このボタンには、親コンポーネントからonclickプロパティとして渡された関数をイベントハンドラとして設定する。これにより、ボタンがクリックされたときに、親コンポーネントで定義された処理が実行される。重要なのは、ボタンコンポーネント自体はクリック時の具体的な動作を知らず、単に親から指示された関数を実行する点だ。

次に、このボタンをラップしてスタイルを適用したFancyButton.svelteを作成する。このコンポーネントは、Button.svelteをインポートし、class="fancy"というスタイルを適用する。さらに重要なのは、親コンポーネントから受け取ったonclickプロパティを、内部のButton.svelteにそのまま渡すことだ。これがないと、クリックイベントはFancyButton.svelteで止まってしまい、親コンポーネントに伝わらなくなる。FancyButton.svelteは、見た目を装飾するだけで、クリック時の動作には関与しない、透過的なラッパーとして機能する。

親コンポーネントでの使用例を見てみよう。+page.svelteで、FancyButton.svelteをインポートし、countという変数を定義する。handleClick関数は、このcountをインクリメントする。そして、FancyButton.svelteonclickプロパティとしてhandleClick関数を渡す。これにより、ボタンがクリックされるたびに、handleClickが実行され、countが増加する。

イベントフォワーディングを行わない場合を考えてみよう。BrokenFancyButton.svelteを作成し、Button.svelteをインポートするが、onclickプロパティを渡さない。このコンポーネントを親コンポーネントで使用しても、クリックイベントは親に伝わらず、handleClickは実行されない。

イベントフォワーディングは、クリックイベントだけでなく、他のイベントにも適用できる。TextField.svelteというテキスト入力コンポーネントを作成し、oninputonfocusonblurといったイベントハンドラを親コンポーネントから受け取り、<input>要素に直接渡す。これにより、テキスト入力の変化、フォーカスの取得、フォーカスの喪失といったイベントを親コンポーネントで処理できるようになる。

イベントフォワーディングは、コンポーネントのAPIを明確にする効果もある。フォワーディングするイベントを選択することで、親コンポーネントが必要とする情報のみを提供できる。

コンポーネントには、制御されたコンポーネントと制御されていないコンポーネントという2つのタイプがある。制御されていないコンポーネントは、内部で状態を管理し、親コンポーネントは状態を知らない。一方、制御されたコンポーネントは、親コンポーネントから状態を受け取り、表示を更新する。親コンポーネントは、状態を完全に制御できる。

制御されていないコンポーネントの例として、UncontrolledInput.svelteがある。このコンポーネントは、内部でtextという変数を定義し、<input>要素とバインドする。親コンポーネントは、このtextの値を知らない。制御されたコンポーネントの例として、ControlledInput.svelteがある。このコンポーネントは、親コンポーネントからvalueプロパティを受け取り、<input>要素とバインドする。親コンポーネントは、valueの値を制御できる。

どちらのタイプを使用するかは、親コンポーネントが状態を管理する必要があるかどうかによって決まる。親コンポーネントが状態を管理する必要がある場合は、制御されたコンポーネントを使用する。そうでない場合は、制御されていないコンポーネントを使用する。

最後に、チャット入力コンポーネントの例を見てみよう。このコンポーネントは、絵文字ピッカーを表示し、テキスト入力を受け付ける。親コンポーネントは、送信ボタンがクリックされたときにメッセージを受け取る。このコンポーネントは、props、bindings、events、forwardingの4つのテクニックを組み合わせて実現されている。

絵文字ピッカーコンポーネントEmojiPicker.svelteは、親コンポーネントからonselectコールバックを受け取る。絵文字がクリックされると、onselectコールバックが呼び出される。チャット入力コンポーネントChatInput.svelteは、親コンポーネントからonsend関数を受け取る。テキストが入力され、送信ボタンがクリックされると、onsend関数が呼び出される。親コンポーネントは、メッセージのリストを管理し、ChatInput.svelteからメッセージを受け取るたびに、リストに追加する。

関連コンテンツ