以前の演習では、状態は深くリアクティブであることを学びました—例えば、オブジェクトのプロパティを変更したり、配列にプッシュしたりすると、UIが更新されます。これは、読み取りと書き込みをインターセプトするプロキシを作成することによって機能します。
場合によっては、それが望ましいものではないこともあります。個々のプロパティを変更していない場合、または参照の等価性を維持することが重要である場合は、代わりにローデータ状態を使用できます。
この例では、Svelteの着実に上昇する株価のチャートがあります。新しいデータが入力されたときにチャートを更新したいのですが、これはdata
を状態にすることで実現できます...
アプリ
let data = $state(poll());
...しかし、数ミリ秒後に破棄される場合は、深くリアクティブにする必要はありません。代わりに、$state.raw
を使用します。
アプリ
let data = $state.raw(poll());
ローデータ状態の変更は、直接的な影響を与えません。一般的に、非リアクティブな状態の変更は強く推奨されません。
前へ 次へ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<script>
import { scale } from './utils.js';
import { poll } from './data.js';
let data = poll();
let w = $state(1);
let h = $state(1);
const min = $derived(Math.min(...data) - 5);
const max = $derived(Math.max(...data) + 5);
const x = $derived(scale([0, data.length], [0, w]));
const y = $derived(scale([min, max], [h, 0]));
const ticks = $derived.by(() => {
const result = [];
let n = 10 * Math.ceil(min / 10);
while (n < max) {
result.push(n);
n += 10;
}
return result;
});
$effect(() => {
const interval = setInterval(() => {
data = poll();
}, 200);
return () => {
clearInterval(interval);
};
});
</script>
<div class="outer">
<svg width={w} height={h} bind:clientWidth={w} bind:clientHeight={h}>
<line y1={h} y2={h} x2={w} />
{#each ticks as tick}
<g class="tick" transform="translate(0,{y(tick)})">
<line x2={w} />
<text x={-5}>{tick}</text>
</g>
{/each}
<polyline points={data.map((d, i) => [x(i), y(d)]).join(' ')} />
<text x={10} y={10} font-size={36}>$SVLT</text>
</svg>
</div>
<style>
.outer {
width: 100%;
height: 100%;
padding: 2em;
box-sizing: border-box;
}
svg {
width: 100%;
height: 100%;
overflow: visible;
}
polyline {
fill: none;
stroke: #ff3e00;
stroke-width: 2;
stroke-linejoin: round;
stroke-linecap: round;
}
line {
stroke: #aaa;
}
.tick {
stroke-dasharray: 2 2;
text {
text-anchor: end;
dominant-baseline: middle;
}
}
</style>