На первый взгляд похож на React… но радикально отличается

Solid JS — относительный новичок на сцене фреймворка JavaScript. И все же он занимает первое место по популярности в опросе State of JavaScript этого года. Что делает его таким привлекательным и стоит ли этому учиться?

Это как React… на первый взгляд

Когда вы читаете код SolidJS, он выглядит много как React. Компонент — это функция, которая возвращает код JSX. Если вы хоть немного знакомы с React, вы можете прочитать код SolidJS и получить представление о том, что происходит. На самом деле следующий код действителен как в React, так и в Solid:

function MyComponent(props) {
  return <div>Hello {props.name}</div>;
}

<MyComponent name="Solid" />;

И это хорошо. Уже существует достаточно разных фреймворков, каждый из которых использует свой синтаксис. А React является стандартом де-факто. Так что приятно находиться на знакомой территории.

За исключением того, что это не так. Потому что хуки, которые являются основой бизнес-логики React, даже не существуют в Solid JS.

Использование сигналов вместо useState

Solid не имеет хука useState. Вместо этого он полагается на «сигналы». Что такое сигнал? В Solid сигналы инициализируются следующим образом:

const [count, setCount] = createSignal(0);

Учитывая знакомый синтаксис, легко представить, что createSignal — это просто вариант «useState» React. И в некотором смысле оба служат для решения одной и той же проблемы: отслеживания состояния приложения при выполнении функций компонента. Так в чем же разница между сигналами SolidJS и хуками useState React?

Первый намек на подсказку заключается в том, что первый элемент, возвращаемый createSignal (поэтому «count» в приведенном выше примере), является функцией. На веб-сайте Solid JS говорится: «Сигналы — это генераторы событий, которые содержат список подписок». Что это означает на практике?

В документации также указано, что функции компонентов «вызываются один раз и затем перестают существовать». Они «существуют для организации вашего кода и не более того». Таким образом, несмотря на сходство в том, как написан код, кажется, что лежащие в его основе механизмы сильно различаются.

React отслеживает изменения состояния в дереве компонентов с помощью Virtual DOM. А затем React перерисовывает дерево в зависимости от того, где в дереве происходят изменения. Дерево сравнивается. И функции компонента вызываются неоднократно. Весь компонент и его дочерние элементы перерисовываются всякий раз, когда изменяется какая-либо часть его состояния.

С другой стороны, Solid отслеживает, какая часть пользовательского интерфейса от чего зависит. И он обновляет это и ничего больше.

И это кажется очень знакомым

Solid управляет состоянием, как Svelte

Svelte претендует на роль исчезающего фреймворка. Вместо того, чтобы сравнивать изменения состояния в виртуальной модели DOM (как это делают React и другие), он перегружает синтаксис JavaScript для отслеживания зависимостей. В этом смысле это прежде всего компилятор. И поскольку он знает, какая часть интерфейса зависит от какой переменной, он хирургически точен в своих обновлениях.

То, что делает Solid JS, очень похоже на это: изменяемые части интерфейса подключаются к обработчикам событий. Побочные эффекты (эквиваленты useEffect) подключаются к этим прослушивателям событий.

Так почему бы просто не использовать Svelte или React вместо того, чтобы обратиться к какому-нибудь (относительно) новому выскочке?

Имеет смысл

Для меня (и это вполне может быть просто делом вкуса) Svelte слишком похож на волшебство. Это похоже на JavaScript, но компилятор наслаивает темные искусства зависимостей поверх этого.

Solid, с другой стороны, имеет больше смысла, чем Svelte. Это просто умно организованные прослушиватели событий, а не какая-то магия компилятора. Я знаю, понимаю и доверяю прослушивателям событий. Компиляторы делают странные вещи с моим кодом… не так уж и много.

Если подумать, Solid даже более логичен, чем React. Ошибки, которые я видел у младших разработчиков, показывают, что они не понимают, когда вызываются функциональные компоненты или как управляется состояние.

И в каком-то смысле это самое сложное в Solid JS.

Концепции, которые я узнал о React, которые укоренились в том, как я кодирую, о том, как управлять состоянием и рендерингом, плохо переносятся в Solid JS. Мне не нужно беспокоиться о том, как часто вызываются компоненты, потому что они вызываются только один раз.

В обоих этих случаях, в том, как Solid реализует реактивность и управляет рендерингом HTML, Solid кажется более разумным, чем его «родители», Svelte и React.

Лучше, чем сумма его частей?

Все это объединяется для создания эффективного и быстрого кода. Solid JS получил очень высокие оценки в тесте JavaScript framework. Он очень высоко оценивается в опросе State of JavaScript. И весит всего 7кб.

Так почему же я пока не буду использовать Solid JS?

Ну, часть проблемы в том, что Solid JS — это не React, и многие проекты, в которых я участвую, уже имеют большую кодовую базу React. Люди, работающие над ними, знают React и не знают Solid.

Но у меня есть ощущение, что то здесь, то там, где React вызывал проблемы с производительностью, в проектах, где я могу работать один, я буду добавлять немного Solid JS здесь и там.

И кто знает, может быть, когда-нибудь я буду использовать исключительно его. Потому что мне нравится реактивность Svelte, но я не фанат магии его компилятора. И мне нравится синтаксис и простота React JSX, но я видел слишком много людей, сбитых с толку поведением, которое они не понимают.

И Solid JS выглядит так, как будто он может объединить лучшее из обоих миров таким образом, чтобы он был простым, разумным и… надежным.

Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter и LinkedIn. Посетите наш Community Discord и присоединитесь к нашему Коллективу талантов.