Reactでいうところの`ref`を、Svelteでどうやって扱うか。
まぁドキュメントにちゃんと書いてあるけども。
bind:this
1つ目のやり方がこれ。
<script> import { onMount } from "svelte"; let el = null; onMount(() => { const timer = setInterval( () => el.textContent = Date.now(), 1000 ); return () => clearInterval(timer); }); </script> <div bind:this={el} />
`bind:this`ディレクティブで、変数に入れる。
そしてその変数は、`onMount()`のフックで取る。
そうしないと、まだレンダリングされてないので、`undefined`になっちゃう。
use:action
2つ目のやりかた。
<script> import { myAction } from "./actions.js"; </script> <div use:myAction />
というように、`use:関数名`って書く。
関数側はこのように。
export const myAction = (el) => { const timer = setInterval( () => el.textContent = Date.now(), 1000 ); return { destroy() { clearInterval(timer); }, }; };
`destory()`はこのDOM要素が破棄されるタイミングで呼ばれる。
こうすると、それ用の関数に処理を切り出せていい感じ。
パラメータを渡す
ちなみにDOM要素のほかにパラメータを受け取るためには、ディレクティブで渡せばよい。
<div use:myAction={2000} /> <div use:myAction2={{ foo, bar }} />
こうすると、第2引数で取れるようになる。
export const myAction = (el, duration = 1000) => { const timer = setInterval( () => el.textContent = Date.now(), duration ); return { destroy() { clearInterval(timer); }, }; };
渡したパラメータが更新されたら
リアクティブな値を渡した場合など。
export const myAction2 = (el, params) => { return { update(params) { // Do something }, destroy() {}, }; };
`update()`を用意しておくと、値が変わったときに呼ばれるようになる。