Знакомство с рунами: волшебное путешествие реактивности

Помните время, когда мы все воскликнули: «Ого!» со Svelte 3? Тот потрясающий момент, когда JavaScript волшебным образом превратился в реактивный язык? Ах, хорошие времена! Вот мы и набросали код, который был аккуратно оптимизирован благодаря способности компилятора Svelte играть в прятки с нашими переменными состояния.

<script>
 let count = 0;

 function increment() {
  count += 1;
 }
</script>

<button on:click={increment}>
 clicks: {count}
</button>svejavajava

Но вы знаете, что? Люди! Мы никогда не бываем по-настоящему удовлетворены.

Руны — что это?

Честно говоря, когда я впервые услышал это имя, я представил себе волшебников, творящих заклинания (я виню в этом Гарри Поттера). Но во вселенной Svelte руны подобны магическим символам, которые мягко шепчут компилятору Svelte.

Раньше Svelte смотрела на let, =, export и $:, чтобы понять назначение нашего кода. Но руны? О, они элегантно используют синтаксис функций для этого и многого другого.

Взгляни:

<script>
 let count = $state(0);

 function increment() {
  count += 1;
 }
</script>

<button on:click={increment}>
 clicks: {count}
</button>

Ага! Итак, вместо старого доброго let у нас теперь есть $state. Но почему? Разве простота не является визитной карточкой Svelte? Действительно, но по мере того, как наши приложения начали носить все больше шляп и танцевать на более крупных аренах, границы между тем, что реактивно, а что нет, начали стираться. Руны своим волшебным образом проясняют это различие и помогают нам писать более последовательный код.

Реактивность за пределами компонентов

Здесь все становится еще интереснее. Подумайте о тех случаях, когда вам хотелось использовать одну и ту же логику для нескольких компонентов. Обычно вы создаете собственное хранилище в файле .js или .ts.

С рунами дела обстоят немного иначе. Больше никаких причудливых API-интерфейсов магазинов. Просто чистая, неподдельная простота:

export function createCounter() {
 let count = $state(0);

 return {
  get count { return count },
  increment: () => count += 1
 };
}

Обратите внимание на использование здесь свойства get. Это гарантирует, что всякий раз, когда вы ссылаетесь на counter.count, он всегда возвращает самое последнее значение. Сладкий!

Реактивность во время выполнения? Черт, да!