概要
ソースレビュー中に「あれ、これって良いんだっけ?」と思ったコード。実際のソースコードを貼るわけにはいかないので、下記はイメージ。だいたいやってる処理は同じ。ソースは Vue.js + TypeScript 。
@Component
export default class Computed extends Vue {
// dataに配列を持つ
listOdd: number[] = [];
listEven: number[] = [];
/**
* クリック時に配列の更新を行う
* forでループして、iの値によって別のlistにpushする
*/
onClick() {
for (let i = 0; i < 100; i++) {
if (i % 2 === 1) {
this.listOdd.push(i);
} else {
this.listEven.push(i);
}
}
}
// それぞれ配列の算出プロパティ
get backOdd() {
return this.listOdd[this.listOdd.length - 1];
}
get backEven() {
return this.listEven[this.listEven.length - 1];
}
}
疑問に思ったこと
あれ?と思ったのはソースのここ。
for (let i = 0; i < 100; i++) {
if (i % 2 === 1) {
this.listOdd.push(i);
} else {
this.listEven.push(i);
}
}
プロパティに毎回 push をしている。ループが走るごとに data が更新されてしまっている。
- 算出プロパティが無駄に更新されてしまわないか?
- レンダリングがループのたびに発生しないか?
とか思ってしまった。特に、最近の JavaScript の書き方を使えばリスト処理は for を使わなくてもかけるので、 for でゴリっと書かれていた処理に違和感があったのも事実。
問題ないか確かめてみる
console を仕込んで、computed,updated がどのタイミングで呼ばれるか確認した。
onClick() {
for (let i = 0; i < 100; i++) {
console.error("loop"); // console
if (i % 2 === 1) {
this.listOdd.push(i);
} else {
this.listEven.push(i);
}
}
}
updated() {
console.warn("updated"); // console
}
get backOdd() {
console.warn("backOdd"); // console
return this.listOdd[this.listOdd.length - 1];
}
get backEven() {
console.warn("backEven"); // console
return this.listEven[this.listEven.length - 1];
}
結果 ➡️ 問題なかった
ちゃんとループが終わってから computed も updated も実行された。どうやらイベントが終わるまでは更新を待ってくれているらしい。ソースレビューでの不安は杞憂に終わった。
