🌊
Svelteでリストが増えたら再レンダリングしたい!
こんにちは、フクロウです。
レンダリングのを調べたキッカケ
Svelteを試すためにでtodoアプリを作っていた時、todoリストを追加しても、画面表示されなくてどうしたものか...なかなか答えが出ず...
調べた結果、重要なのは「{#key}」を使うことでした。
keyで指定された変数の変更を検知して、{#key}で囲った場所のみを再レンダリングされるようです。
ソースコード
ソースコードをどうぞ!
<script>
const dataList:number[] = [0]
let dataCount:number = 0
function push() {
dataCount++;
dataList.push(dataList.length)
}
</script>
<button type="button" on:click={push}>追加</button>
{#key dataCount}
{dataList}
{/key}
では、子コンポーネントの再レンダリングしたい場合はどうなるのか?
親コンポーネント
<script>
import Item from './components/Item.svelte';
const dataList:number[] = []
let dataCount:number = 0
function push() {
dataList.push(dataList.length)
dataCount = dataList.length
}
</script>
<button type="button" on:click={push}>追加</button>
{#key dataCount}
<Item dataList={dataList}>
{/key}
子コンポーネント
<script>
// expotと書くだけでsvelteは親から子供へ値を受け渡せます。
export let dataList:number[]
</script>
// あとはdataListを自由に使うだけ!
{#each dataList as data}
{data}
{/each}
はい!これだけでできます。
余談
試してみて分かったのですが、{#key dataList.length} で変更検知をしてくれるかやってみましたが、dataList.pushでは変更検知はされませんでした。
{#key dataList.length} で変更検知を行う場合は、毎回、対象の配列を初期化しないとできません。
何かわからないことがあれば、コメントください。
Discussion
こんにちは
svelte4までは、変更をコンパイラに知らせるには代入を用いる必要があります。
そのため本文中にある通り、
list.push(hoge)
では変更は検知されないです代入構文を使うとこうなります。
ちなみに来たるsvelte5では、runeを用いることで明示的に変化する変数をコンパイラに伝えることができるため
.push
を用いても変更は検知されますありがとうございます!
勉強になります!