Riot 3.7では、ループするタグにkey
属性を加えることができるようになっています。
Riotでのループ
改めて説明するまでもないかもしれませんが、Riotではeach={item in items}
のようにすることで、配列などを展開してそれぞれごとに要素を生成することができます。
key
なしでの場合
key
のない場合、配列を変更した後にupdate
するとなると、DOM要素は適宜使いまわされることになります。通常の場合はそれでかまわないのですが、Riotで管理していない属性、例えば以下のようなものがある状況だと、それがきちんと対応しなくなります。
- フォーカスの状態(一覧表に行を上下させるためのボタンを付けると、行の中身は移動したのにフォーカスだけもとのままとか、見栄えの悪い動作になることがあります)
-
<input type='file'>
の中身(onchange
ですぐFormData
に起こして管理する、というような場合を除けば、送信すべきデータをそのまま引き回すためにはDOM要素ごと移動させるぐらいしか手段がありません)
また、値が移動した場合の照合はArray.prototype.indexOf
で行っている加減で、巨大なリストになれば線形探索のコストが無視できなくなってきます。
key
を入れた場合
これらの問題は、key
を指定することで解決できます。キーはindexOf
のリニアサーチよりずっと早く照合できますし1、key
付きのDOMは、きちんと配列要素と対応して移動してくれます。key
の指定方法には2通りあって、
-
key='property'
…ループオブジェクトの.property
の値をそのままkey
として使う。 -
key={...}
…JavaScriptの式でキーを生成する
というようになっています。
注意点
その性質上、key
が重複したり途中で書き換わったりしてしまうと、走査が正常に行われなくなります。データベースに入っているものならPRIMARY KEYをそのまま使えばいいのでしょうけど、そうでない場合には注意が必要です。ループで回す要素を追加する場合、追加時点でkey
となる値は確実にセットする必要があります。
外部リンク
-
「This will improve massively the loop performance in case your collections are immutable.」が何故早くなるのか、この解釈とは違うかもしれません。 ↩