Основа SolidJS — реактивная система, построенная на примитивах (`createSignal`, `createEffect`, `createMemo`), напоминающих хуки React, но работающих на принципиально ином уровне. `createSignal` возвращает геттер и сеттер, а не значение и функцию. Это ключевое отличие.
import { createSignal, createEffect } from 'solid-js';
function Counter() {
const [count, setCount] = createSignal(0); // count — это функция-геттер
createEffect(() => {
console.log('Текущее значение:', count()); // Вызываем как функцию!
});
return (
setCount(count() + 1)}>
Кликов: {count()} {/* Тоже вызываем! */}
);
}
Первый и главный совет: всегда помните, что реактивное состояние в Solid — это функция (`count()`), а не значение. Это позволяет фреймворку точно отслеживать зависимости и обновлять только те части DOM, которые действительно изменились.
Разберем производительность. Поскольку SolidJS компилирует JSX, он знает, как разделить ваш компонент на статичные и динамические части. Директивы, такие как `/* @once */` для JSX, позволяют дать компилятору дополнительные подсказки.
// Компилятор оптимизирует этот элемент, зная, что `staticValue` никогда не изменится.
const staticValue = /* @once */ "Я статичен";
return {staticValue}
Совет второй: для списков всегда используйте встроенный компонент ``, а не `map`. `` использует ключи и эффективно обновляет только измененные элементы, не пересоздавая весь список.
import { For } from 'solid-js';
const [todos, setTodos] = createSignal([{id: 1, text: 'Выучить Solid'}]);
return (
-
{(item) =>
- {item.text}
Управление побочными эффектами и ресурсами — сильная сторона Solid. Примитив `createResource` предназначен для асинхронных операций, таких как загрузка данных. Он автоматически управляет состояниями «загрузки» и «ошибки».
import { createResource } from 'solid-js';
const fetchUser = async (id) => (await fetch(`/api/user/${id}`)).json();
function UserProfile({ userId }) {
const [user, { mutate, refetch }] = createResource(userId, fetchUser);
return (
<p>Загрузка...</p>
<p>Ошибка: {user.error.message}</p>
<h1>{user().name}</h1>
);
}
Совет третий: используйте ``/`` для условного рендеринга на основе состояния ресурса или сигнала. Это идиоматично и эффективно.
SolidJS предлагает мощные инструменты для управления рендерингом: порталы (``), приостановку рендеринга (``) и динамическую загрузку компонентов (`lazy`). `` может обернуть несколько асинхронных ресурсов и показать fallback.
import { Suspense, lazy } from 'solid-js';
const LazyComponent = lazy(() => import('./HeavyComponent'));
function App() {
return (
);
}
Совет четвертый: не бойтесь использовать `createStore` для более сложного, вложенного состояния. В отличие от сигналов, store использует прокси и позволяет делать мутации «путем» (path), оставаясь реактивным.
import { createStore } from 'solid-js/store';
const [state, setState] = createStore({ user: { name: 'Алекс', settings: { theme: 'dark' } } });
// Глубокая мутация остается реактивной
setState('user', 'settings', 'theme', 'light');
console.log(state.user.settings.theme); // 'light'
Совет пятый, касающийся архитектуры: SolidJS поощряет разделение логики и представления через создание собственных примитивов и использование контекста (`createContext`). Это делает код более тестируемым и переиспользуемым.
import { createContext, useContext } from 'solid-js';
const AuthContext = createContext();
export function AuthProvider(props) {
const [user, setUser] = createSignal(null);
const store = { user, login: setUser, logout: () => setUser(null) };
return (
{props.children}
);
}
export function useAuth() { return useContext(AuthContext); }
В итоге, SolidJS — это фреймворк, требующий переосмысления подхода к реактивности. Его сила — в отсутствии накладных расходов Virtual DOM, точных обновлениях и простой ментальной модели. Ключевые советы: думайте в терминах геттеров сигналов, используйте встроенные компоненты управления потоком (``, ``, ``), грамотно работайте с асинхронностью через `` и `createResource` и структурируйте состояние с помощью `createStore` для сложных объектов.
Комментарии (5)