Первая и самая частая ошибка — **непонимание реактивности Svelte**. Разработчики, пришедшие из React или Vue, ожидают, что для обновления состояния нужно вызывать специальную функцию (`setState`, реактивные геттеры/сеттеры). В Svelte реактивность объявлятельная. Ошибка: попытка мутировать переменную без использования оператора присваивания (`=`), который является триггером для реактивности.
```svelte
let count = 0;
let doubled = 0;
// ОШИБКА: Это не вызовет обновления doubled в DOM.
function increment() {
count += 1;
doubled = count * 2; // Это сработает, потому есть присваивание.
}
// Ещё одна частая ошибка с массивами и объектами
let items = ['apple', 'banana'];
function addItemBad(item) {
items.push(item); // ОШИБКА: Мутация массива. DOM не обновится!
console.log(items); // В консоли массив изменился, но интерфейс — нет.
}
function addItemGood(item) {
items = [...items, item]; // ПРАВИЛЬНО: Присваивание нового массива.
}
Count: {count}
<p>Doubled: {doubled}</p>
```
Решение всегда одно: для обновления реактивных переменных, включая свойства объектов и элементы массивов, используйте оператор присваивания. Для удобства Svelte предоставляет синтаксис `$:` для реактивных объявлений, которые автоматически пересчитываются при изменении зависимостей.
Следующая ловушка — **неправильное использование директивы `$:` (реактивного оператора)**. Новички пытаются использовать его для всего подряд, включая side-эффекты с непредсказуемыми последствиями.
```svelte
let width = 0;
let height = 0;
let area = 0;
// ОШИБКА: Побочный эффект (console.log) внутри реактивного блока может запускаться чаще, чем ожидается.
$: {
area = width * height;
console.log('Area recalculated:', area); // Будет логироваться при любом изменении width или height.
}
// ЛУЧШЕ: Выносить side-эффекты в отдельные функции или использовать блочный оператор аккуратно.
$: area = width * height;
$: console.log('Area recalculated:', area); // Отдельный реактивный оператор для side-эффекта более предсказуем.
// ОШИБКА: Бесконечный цикл.
$: width = area / height; // Если area и height изменятся, изменится width, что снова запустит этот блок...
```
Правило: используйте `$:` для вычисляемых значений, которые *зависят* от других реактивных данных. Избегайте взаимозависимых реактивных операторов, создающих циклы.
Третья критическая ошибка в первые минуты — **игнорирование особенностей жизненного цикла компонентов**. Svelte предоставляет удобные функции `onMount`, `beforeUpdate`, `afterUpdate`, `onDestroy`. Типичный сценарий: попытка получить доступ к DOM-элементу сразу при инициализации компонента, когда его ещё не существует в DOM.
```svelte
import { onMount } from 'svelte';
let myDiv;
let content = '';
// ОШИБКА: Элемент myDiv ещё не привязан к DOM на этапе инициализации скрипта.
// content = myDiv.innerText; // myDiv === undefined
// ПРАВИЛЬНО: Использовать onMount или реактивный оператор после привязки элемента.
onMount(() => {
// Теперь DOM смонтирован, и myDiv доступен.
if (myDiv) {
content = `Div is mounted with width: ${myDiv.offsetWidth}`;
}
});
// Или через реактивное объявление, которое сработает после привязки myDiv
$: if (myDiv) {
// Будет выполнено каждый раз, когда меняется ссылка myDiv (после монтирования).
}
Some content
<p>{content}</p>
```
Четвёртая проблема — **непонимание передачи данных между компонентами (props)**. В Svelte пропсы объявляются с помощью ключевого слова `export`. Ошибка: попытка мутировать пропс, полученный от родительского компонента, что нарушает принцип однонаправленного потока данных.
```svelte
export let value; // Пропс от родителя
function updateBad() {
value += 1; // ОШИБКА: Прямая мутация пропса. Родитель не узнает об этом стандартным образом.
}
// ПРАВИЛЬНЫЙ ПАТТЕРН: Отправка события родителю.
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function updateGood() {
dispatch('updateRequest', { newValue: value + 1 });
}
Request Update
```
Родительский компонент должен обрабатывать событие и менять данные сам.
Наконец, ошибка **пренебрежения встроенными анимациями и переходами**. Svelte предлагает мощные, простые в использовании директивы `animate`, `transition`, `in:out`. Новички часто пишут свои сложные CSS- или JS-анимации, не замечая, что Svelte может сделать это в одну строку.
```svelte
import { fade, fly } from 'svelte/transition';
import { flip } from 'svelte/animate';
let visible = true;
let list = [1, 2, 3];
{#if visible}
<p transition:fade={{ duration: 300 }}>Плавно появляюсь и исчезаю</p>
{/if}
-
{#each list as item (item)}
- {item} {/each}
Потратив первые 30 минут на изучение этих принципов, а не на борьбу с ошибками, вы заложите прочный фундамент для своего Svelte-проекта. Запомните: реактивность через присваивание, аккуратное использование `$:`, уважение к жизненному циклу, неизменяемость пропсов и использование встроенных инструментов анимации. Это позволит вам наслаждаться истинной простотой Svelte, а не бороться с её скрытой сложностью.
Комментарии (5)