Solid.js — это современный фреймворк для разработки пользовательских интерфейсов, ориентированный на максимальную производительность. Одной из важнейших составляющих этого фреймворка является система реактивности, которая позволяет отслеживать изменения состояния и автоматически обновлять интерфейс. Важным аспектом реактивности является управление подписками, которое в Solid.js реализовано с использованием концепции “механизмов” (stores), и позволяет эффективно контролировать и реагировать на изменения данных.
Подписка в контексте Solid.js — это способ отслеживания изменений данных и выполнения действий при изменении этих данных. В Solid.js подписки управляются с помощью реактивных хранилищ (stores) и реактивных деклараций. Когда значение, на которое подписан компонент или функция, изменяется, соответствующий компонент перерисовывается, чтобы отобразить актуальные данные.
В Solid.js хранилища (stores) являются объектами, которые содержат данные, к которым компоненты могут подписываться. Существует несколько видов хранилищ:
Signal — это простой тип хранилища, который
содержит одно значение. Он предоставляет два метода: get()
и set(). Подписка на сигнал осуществляется с помощью его
значения, а обновления происходят при вызове метода
set().
Store — более сложное хранилище, которое поддерживает структуру данных, аналогичную объектам или массивам. В отличие от сигнала, store может быть вложенным и обеспечивать более сложное состояние.
Computed — это вычисляемое значение, которое зависит от других реактивных значений и обновляется автоматически при изменении этих значений.
Сигналы в Solid.js — это простые реактивные переменные, которые представляют собой небольшие фрагменты состояния. Их основное назначение — хранить значения, которые могут изменяться в течение жизненного цикла компонента.
import { createSignal } from 'solid-js';
function Counter() {
const [count, setCount] = createSignal(0); // создаем сигнал с начальным значением
return (
<div>
<p>Счётчик: {count()}</p> {/* Подписка на сигнал */}
<button onCl ick={() => setCount(count() + 1)}>Увеличить</button>
</div>
);
}
В данном примере создаётся сигнал count, который
инициализируется значением 0. При изменении этого значения
компонент автоматически перерисовывается, и новое значение отображается
на экране.
Хранилища предоставляют более сложную структуру для управления состоянием, поддерживая вложенные объекты и массивы. В отличие от сигналов, которые могут хранить только одно значение, хранилища могут содержать более сложные данные, такие как массивы или объекты, и работать с ними через реактивные механизмы.
import { createStore } from 'solid-js/store';
function TodoApp() {
const [todos, setTodos] = createStore([
{ text: 'Изучить Solid.js', completed: false },
{ text: 'Написать статью', completed: true },
]);
return (
<div>
<ul>
{todos.map((todo, index) => (
<li key={index}>
<input
type="checkbox"
checked={todo.completed}
onCha nge={() => setTodos(index, 'completed', !todo.completed)}
/>
{todo.text}
</li>
))}
</ul>
</div>
);
}
В этом примере создается хранилище todos, которое
представляет собой массив объектов. Каждый элемент массива можно
изменять через функцию setTodos. Важным моментом является
то, что обновление любого элемента в массиве вызывает перерисовку
компонента, в котором используется это состояние.
В Solid.js вычисляемые значения (computed) являются
особым типом реактивных данных. Они представляют собой производные
данные, которые автоматически обновляются, если изменяется одно из их
зависимых значений. Это позволяет избежать лишних вычислений и
эффективно управлять состоянием, не создавая лишних подписок.
import { createSignal, createEffect } from 'solid-js';
function TemperatureConverter() {
const [celsius, setCelsius] = createSignal(0);
const fahrenheit = () => (celsius() * 9) / 5 + 32; // вычисляемое значение
return (
<div>
<input
type="number"
value={celsius()}
onIn put={(e) => setCelsius(Number(e.target.value))}
/>
<p>{celsius()}°C = {fahrenheit()}°F</p>
</div>
);
}
Здесь создается вычисляемое значение fahrenheit, которое
зависит от значения celsius. При изменении значения
celsius автоматически пересчитывается значение
fahrenheit и обновляется на экране.
createEffectcreateEffect — это механизм, который позволяет создавать
побочные эффекты в приложении, когда изменяются данные. Эффекты
автоматически выполняются, когда их зависимости изменяются. В отличие от
вычисляемых значений, эффекты не возвращают результат, а скорее
выполняют определённые действия, например, обновление DOM или выполнение
асинхронных операций.
import { createSignal, createEffect } from 'solid-js';
function Timer() {
const [time, setTime] = createSignal(0);
createEffect(() => {
const id = setInterval(() => {
setTime(time() + 1);
}, 1000);
return () => clearInterval(id); // очистка интервала при уничтожении эффекта
});
return <p>Время: {time()}</p>;
}
В данном примере создается эффект, который обновляет состояние времени каждую секунду. Когда компонент удаляется или перестает использоваться, интервал автоматически очищается.
Solid.js предоставляет мощные инструменты для управления подписками и реактивностью в приложении. Использование сигналов, хранилищ и вычисляемых значений позволяет эффективно управлять состоянием и автоматически обновлять интерфейс при изменении данных. Благодаря простоте и гибкости этих механизмов, Solid.js обеспечивает высокую производительность и удобство работы с реактивными состояниями.