Я ошибся?
да. Но не вините себя, ваши ожидания кажутся мне логичными. Но это не так.
Как правило, если где-то в коде вашего компонента есть переменная с префиксом $
, тогда это должно быть хранилище, и она будет подписана сразу при создании компонента и отписана, когда компонент будет уничтожен. .
Небольшое исключение из этого правила было введено совсем недавно (с помощью этого PR). Я позволю вам пройти по следу кроличьей норы, если вы хотите знать всю дискуссию. Суть в том, что теперь подписка магазина должна быть или нулевой (то есть null
или undefined
- см. этот комментарий).
Это означает, что теперь можно при необходимости взломать свой путь к ожидаемому поведению. Мы возвращаемся к этому.
Зачем подписываться на $ store, если canSubscribe ложно?
Потому что на магазины подписываются сразу. Насколько я понимаю, из обсуждения проблем, связанных выше, это для производительности (размер байта) и работоспособности (быстро и заметно сбой, если кто-то пытается подписаться на что-то, что не является магазином). Для меня это имеет смысл.
А теперь вернемся к вопросу, который вы не задавали: как подписаться только тогда / при необходимости? Помещайте хранилище в переменную с автоматической подпиской только тогда, когда это необходимо, и оставляйте его равным нулю в противном случае.
Не делайте:
$: started && $store
Вместо этого сделайте это:
$: proxyStore = started ? store : null
$: console.log($proxyStore)
Полный пример (REPL):
<script>
import { writable } from 'svelte/store'
const state1 = { subscribed: 0, unsubscribed: 0 }
const store1 = writable(42, () => {
state1.subscribed++
return () => {
state1.unsubscribed++
}
})
const state2 = { subscribed: 0, unsubscribed: 0 }
const store2 = writable(43, () => {
state2.subscribed++
return () => {
state2.unsubscribed++
}
})
let started = false
$: started && $store1
$: targetStore = started ? store2 : null
$: $targetStore
</script>
<pre>
started = {started}
store1 = {$store1} {JSON.stringify(state1)}
store2 = {$targetStore} {JSON.stringify(state2)}
</pre>
<button on:click={() => {started = !started}}>
{started ? 'Start' : 'Stop'}
</button>
person
rixo
schedule
19.04.2020