Приведенный ниже код работает так, как должен, я просто пытаюсь лучше понять, почему.
Насколько getCurrentElement
метод TestState
реактивен без использования $derived()
? Являются ли методы хранилища, использующие состояние, реактивными по умолчанию?
Я использую [email protected]
test-store.svelte.ts
import { getContext, setContext } from 'svelte';
class TestState {
elements = [
{
id: 'hghxt',
name: 'Give',
},
{
id: 'vhtl9',
name: 'Connection',
},
{
id: '5n0t0',
name: 'Take notice',
},
{
id: 'xlfba',
name: 'Keep learning',
},
{
id: '1f3z2',
name: 'Be active',
},
];
#currentElementId = $state<string>();
getCurrentElement() {
return this.elements.find(element => element.id === this.#currentElementId);
}
setCurrentElement(id: string) {
if (!this.elements.some(element => element.id === id)) return;
this.#currentElementId = id;
}
}
const TEST_STORE_KEY = Symbol('TEST_STORE');
export function setTestState() {
return setContext(TEST_STORE_KEY, new TestState());
}
export function getTestState() {
return getContext<ReturnType<typeof setTestState>>(TEST_STORE_KEY);
}
TestComponent.svelte
<script lang = "ts">
import { getTestState } from '$lib/stores/test-store.svelte';
// initialised at +page.svelte
const testState = getTestState();
</script>
{#each testState.elements as { name, id }}
<button
class:bg-yellow = {testState.getCurrentElement()?.id === id}
onclick = {() => testState.setCurrentElement(id)}>
{name}
</button>
{/each}
🤔 А знаете ли вы, что...
JavaScript поддерживает модульную структуру, что способствует организации кода на больших проектах.
В своем «HTML-коде» вы называете testState.getCurrentElement()
. Когда вы это сделаете, Svelte заметит, от каких реактивных переменных зависит этот вызов. В getCurrentElement()
вы получаете доступ к this.#currentElementId
, поэтому Svelte знает, что эту часть «HTML-кода» необходимо повторно отобразить/обновить, когда this.#currentElementId
присвоено новое значение.
Вам нужно использовать $derived()
только тогда, когда вы хотите автоматически вычислить новое значение, как только реактивная переменная изменит значение, и здесь это не тот случай, поэтому я не вижу здесь никакого смысла использовать $derived()
.
@JackTempleman, возможно, мы называем вещи по-разному, но такого понятия, как реактивная функция, не существует, по крайней мере, в моем словаре. У нас есть только реактивные переменные/выражения, которые можно создать с помощью некоторых рун, например $state()
. Если одна из ваших функций использует реактивную переменную/выражение, то сама эта функция не является реактивной; это просто функция, которая использует реактивные переменные/выражения. Только создание такой функции не приведет к самостоятельным пересчетам. Но если вы вызываете/используете такую функцию в некоторых местах, где Svelte отслеживает реактивность (например, в HTML-коде компонента или в некоторых рунах), тогда Svelte узнает о реактивных переменных/выражениях, которые использует функция, и Svelte вызовет функция снова в будущем, когда эти реактивные переменные/выражения изменят значение.