Фреймворк Steroids
Фреймворк Steroids

На старте проекта обычно встает вопрос о выборе готовой ui-библиотеки для решения шаблонных задач, таких как создание форм, инпутов, кнопок и других компонентов. Количество готовых ui-библиотек для React так стремительно растет, что уже сложно остановить свой выбор на какой либо из них. Зато в таком разнообразии каждый может найти библиотеку, подходящую под его задачи. В этой статье хочется рассказать о фреймворке Steroids, который разработан и поддерживается в нашей компании.

Изначально мы не планировали создавать фреймворк, а просто собирали удачные решения рутинных задач. Получился набор полезных утилит и мини-библиотек, который позволял нам работать быстрее. Мы постепенно добавляли в него новые элементы, он рос и видоизменялся, и в итоге вырос в полноценный фреймворк Steroids.

Что же такое Steroids и для каких задач он может подойти?

Steroids — это фреймворк, который задает архитектуру для всего проекта, а также содержит набор как простых, так и комплексных ui-компонентов, инструменты для взаимодействия с бэкендом и работой с формами, компоненты для работы с хранилищем браузера, websocket и другими технологиями.

Фреймворк Steroids подходит для создания полноценного SPA приложения с продуманной архитектурой, которое содержит в себе:

  • роутинг и управление состоянием, в том числе с использованием Redux, React Context;

  • взаимодействие с сервером — отправка запросов, обработка ошибок;

  • работу с формами — валидация, отправка данных на сервер, сохранение данных полей формы в state manager;

  • загрузку и отображение данных в виде списка или таблицы, сортировка, пагинация, фильтрация данных;

  • локализацию всего приложения;

  • использование серверного рендеринга приложения (SSR).

Основные фичи и особенности фреймворка

У фреймворка Steroids много особенностей и фич, о которых стоит рассказать. Всё это точно не влезет в одну статью. Поэтому здесь пойдет речь про некоторые из них:

  • фреймворк задаёт определенную структуру проекта;

  • все ui-компоненты разделены на core и view части;

  • во фреймворк входят не только ui-компоненты, но  и логические компоненты, которые «под капотом» используют другие инструменты или библиотеки.

Структура проекта

Фреймворк Steroids задаёт определенную структуру папок и файлов проекта. Эта структура предполагает отдельные директории для переиспользуемых компонентов, редьюсеров и экшенов, роутов приложения, стилей, модальных окон и так далее. Ниже приведен пример такой структуры:

├── node_modules
├── public
├── src
│   ├── actions
│   ├── reducers
│   ├── modals
│   ├── routes
│   │   └── IndexPage
│   │       └── views
│   │           ├── MyBox.ts
│   │           └── MyBox.scss
│   │       ├── IndexPage.ts
│   │       ├── IndexPage.scss
│   │       └── index.ts
│   ├── shared
│   │   └── Layout
│   │       ├── Layout.ts
│   │       ├── Layout.scss
│   │       └── index.ts
│   ├── ui
│   │   └── form
│   │       ├── Button
│   │       │   ├── ButtonView.tsx
│   │       │   └── ButtonView.scss
│   │       └── CustomField
│   │           ├── CustomField.ts
│   │           ├── CustomFieldView.tsx
│   │           └── CustomFieldView.scss
│   ├── style
│   │   ├── index.scss
│   │   └── variables.scss
│   ├── Application.tsx
│   └── index.tsx
├── .eslintrc
├── index.d.ts
├── package.json
├── tsconfig.json
├── webpack.js
└── yarn.lock

Созданное на основе Boilerplate приложение имеет нужную структуру, в нём созданы все необходимые папки и файлы. Оно представляет собой тривиальное SPA-приложение с единственной страницей, и сразу после развертывания готово к запуску. Это приложение можно наполнить своими страницами и компонентами, располагая их в соответствующих структуре папках.

Разделение логики и отображения компонентов

Чтобы логика работы компонента была отделена от его отображения, каждый ui-компонент разделён на core и view часть.

Core — ядро компонента. Оно содержит всю бизнес-логику компонента, принимает и обрабатывает полученные данные из props, находит или получает нужную «вьюшку» (view-часть компонента) и прокидывает в неё подготовленные данные. Core-компонент практические не содержит jsx кода и обращений напрямую к DOM.

View — отображение компонента. Это часть, которая отвечает за непосредственную отрисовку компонента. Как правило она содержит только jsx код и scss стили компонента, без бизнес-логики. При кастомизации компонента его View.tsx и/или View.scss файлы при необходимости могут полностью копироваться из фреймворка Steroids и изменяться под дизайн конкретного проекта.

Если при разработке достаточно стандартного отображения компонента, то его можно просто импортировать из core-части фреймворка Steroids (npm-пакет @steroids/core) и использовать в нужном месте. Если же есть потребность как-то кастомизировать компонент под дизайн проекта, то можно воспользоваться несколькими способами, один из которых работает как раз благодаря разделению компонента на core- и view-части.

Вот три основных способа кастомизации:

  1. Передача через пропсы css-классов или объекта style.

  2. Переопределение css-переменных.

  3. Переопределение view-части компонента — его стилей или tsx-кода.

Как использовать первые два способа, думаю, понятно. Они есть в большинстве готовых ui-библиотек. Поэтому перейдем к примерам того, как можно переопределить view часть.

Первый и самый простой способ — передать кастомное отображение через проп view:

const CustomInputFieldView = (props: IInputFieldViewProps) => (
   <div>
       <span>Кастомное отображение инпута</span>
       <input
           {...props.inputProps}
           placeholder={props.placeholder}
           disabled={props.disabled}
           required={props.required}
       />
   </div>
);

const MyForm = () => (
   <Form>
       {/* инпут со стандартным отображением */}
       <InputField attribute='name' />
       {/* инпут с кастомным отображением */}
       <InputField
           attribute='surname'
           view={CustomInputFieldView}
       />
   </Form>
);

Этот способ подойдет, если нужно переопределить какой то конкретный компонент, например инпут для поиска в шапке сайта. Если же нужно добавить кастомное отображение для всех инпутов в проекте, то лучше воспользоваться другим способом.

Второй способ заключается в полной замене стандартных view-частей компонентов на кастомные. В этом случае «вьюшки» применяются ко всем компонента сразу, например ко всем Button или ко всем Form.

Файлы со стилями компонентов подключаются в src/style/index.scss через конструкцию @use, например:

@use '~@steroidsjs/bootstrap/form/InputField/InputFieldView';

А файлы с tsx-кодом компонента в src/ui/bootstrap.ts, например:

'form.InputFieldView': {
   lazy: () => require('@steroidsjs/bootstrap/form/InputField/InputFieldView').default
},

Чтобы переопределить view-часть, достаточно изменить пути к файлам — к scss-файлу или tsx-файлу, смотря что нужно кастомизировать.

Логические компоненты

Одна из особенностей Steroids состоит в том, что «из коробки» доступны не только ui-компоненты, но и логические компоненты или, по другому, компоненты-обертки над другими инструментами и библиотеками. Каждый компонент представляет из себя класс с набором свойств и методов. 

Инициализируются эти компоненты в проекте в файле src/Application.tsx в константе config в поле components:

export const config = {
   reducers: require('./reducers').default,
   routes: () => require('routes').default,
   layoutView: () => require('shared/Layout').default,
   screen: {},
   theme: {},
   components: {
       locale: LocaleComponent,
       http: HttpComponent,
       resource: ResourceComponent,
   },
}

В этом же конфиге можно задать свойства для компонентов, например:

components: {
   http: {
      className: HttpComponent,
      apiUrl: 'https://steroids.dev/',
   },
},

Используются такие компоненты внутри обычных react компонентов, а получить их можно из хука useComponents. Пример:

export default function Header() {
   const bem = useBem('Header');
   const {http} = useComponents();
  
   const [user, setUser] = React.useState(null);

   const getUser = () => http.get('api/v1/user').then(
     response => setUser(response.data)
   );
  
   return (<>...</>)
}

В Steroids реализовано более десяти таких компонентов. Вот основные из них:

HttpComponent — используется для отправки запросов на бекенд, обработки ошибок, авторизации. Поддерживает авторизацию через токен. «Под капотом» использует библиотеку axios.

JwtHttpComponent — расширяет HttpComponent, добавляя функционал обновления токена авторизации.

LocaleComponent — локализует приложение, поддерживает конфигурацию языка и временной зоны.

ClientStorageComponent — работает с хранением данных в браузере (cookie, local/session storage).

WebSocketComponentсоздаёт websocket-соединения и управляет ими

UI-Kit, простые и комплексные компоненты

В Steroids ui-компоненты условно делятся на простые и комплексные.

Простые компоненты — компоненты интерфейса, которые можно использовать независимо от других компонентов, например кнопка, форма, список.

Комплексные компоненты — состоят из простых компонентов, логически связанных между собой, и реализуют какой либо сложный функционал. Примеры таких компонентов — канбан, таблица, чат и др.

Все компоненты в UI-Kit фреймворка Steroids разделены на несколько групп:

  • content;

  • form;

  • layout;

  • list;

  • nav;

  • typography.

В каждой группе собраны компоненты, отвечающие за определенный функционал — отображение контента, формы и списки, навигацию и так далее.

Вот примеры простых ui-компонентов из Steroids, которые наиболее часто используются в проектах:

Accordion — компонент-аккордеон позволяет создавать интерактивные списки или контейнеры, где содержимое может быть развернуто или свернуто по требованию пользователя.

DropDown — компонент, представляющий меню с элементами, которые могут быть выбраны или нажаты. Компонент позволяет отображать и скрывать содержимое меню, а также управлять его позиционированием.

Button — кнопка или ссылка. Используется в интерфейсе для выполнения какого-либо действия по клику.

InputField — поле ввода текста.

NumberField — числовое поле ввода.

FieldList — список из сгруппированных полей формы.

CheckboxField — одиночный чекбокс, использующийся в формах для отметки булевого значения.

Form — компонент для создания формы. Предоставляет управление и синхронизацию состояния формы, а также позволяет выполнять отправку данных формы на сервер с возможностью валидации и обработки результатов.

Notifications — компонент, представляющий собой контейнер для отображения всплывающих уведомлений.

Tooltip — компонент, предоставляющий всплывающую подсказку для дочерних элементов.

Grid — представление данных коллекции в виде таблицы.

List — компонент для представления коллекции в виде списка.

Nav — компонент навигации позволяет переключаться между группами связанного контента.

Комплексные компоненты используются реже, так как реализуют функционал, заточенный под узкий круг сложных задач. 

Вот примеры некоторых компонентов:

CalendarSystem — полноценная система календаря, которая поддерживает создание событий и добавление их групп, разделение событий по пользователям, отображение сетки событий в трёх вариациях — день, неделя и месяц. 

CalendarSystem
CalendarSystem

Kanban — компонент для работы со списком карточек, сгруппированных в списки. Поддерживает функционал создания и редактирования карточек, добавления к ним тегов и описания, открытия карточек в детальном виде — в модальном окне.

Kanban
Kanban

Chat — реализует функционал чата, поддерживает загрузку данных при отправке сообщений, просмотр истории сообщений, разделение сообщений по датам, прикрепление файлов к сообщениям.

Chat
Chat

Остальные простые и комплексные компоненты UI-Kit Steroids можно посмотреть по ссылке — https://steroids.dev/ru/docs/ui.

Сравнение с другими библиотеками

Мы решили сравнить функционал разных ui-библиотек для React, которые пользуются популярностью. Для сравнения выбрали несколько пунктов, которые считаем важными при выборе библиотеки:

  • наличие UI-Kit;

  • готовая архитектура для проекта;

  • подключенные «под капотом» базовые зависимости для создания SPA приложения;

  • работа с формами;

  • работа со списками (в том числе пагинация и фильтрация);

  • работа с роутингом;

  • работа с SSR;

  • возможность кастомизировать компоненты;

  • наличие активного сообщества.

Для сравнения мы выбрали несколько библиотек:

  • Material UI;

  • Ant Design;

  • Mantine;

  • Semantic UI React;

  • Steroids.

Вот что у нас получилось:

Сравнительная таблица библиотек
Сравнительная таблица библиотек

У всех выбранных библиотек есть Ui-Kit и возможность разными способами кастомизировать компоненты. А вот с остальными критериями не все так гладко.

Готовая архитектура проекта, настроенный роутинг и подключенные «под капотом» зависимости есть только у библиотек Material UI, Mantine и Steroids. При чем у Material UI такие функции доступны только в платных шаблонах.

Работа с SSR есть только у двух библиотек — Mantine и Steroids. У первой «под капотом» используется Next.js, а у второй написана собственная реализация SSR, которая подключается через npm-пакет @steroids/ssr.

Посмотрим как обстоят дела с компонентами. В каждой из приведенных библиотек есть компоненты для полей формы, но только в двух из них (все те же Mantine и Steroids) «под капотом» реализована логика работы с формами, а именно валидация значений, обработчик onSubmit, режимы контролируемой и неконтролируемой формы.

Вот пример использования форм, взятый из документации библиотеки Mantine:

import { Button, Checkbox, Group, TextInput } from '@mantine/core';
import { useForm } from '@mantine/form';

function Demo() {
   const form = useForm({
      mode: 'uncontrolled',
      initialValues: {
      email: '',
      termsOfService: false,
   },
   validate: {
      email: (value) => (/^\S+@\S+$/.test(value) ? null : 'Invalid email'),
   },
   });

   return (
      <form onSubmit={form.onSubmit((values) => console.log(values))}>
        <TextInput
           withAsterisk
           label="Email"
           placeholder="your@email.com"
           key={form.key('email')}
           {...form.getInputProps('email')}
        />
        <Checkbox
           mt="md"
           label="I agree to sell my privacy"
           key={form.key('termsOfService')}
           {...form.getInputProps('termsOfService', { type: 'checkbox' })}
        />
        <Group justify="flex-end" mt="md">
           <Button type="submit">Submit</Button>
        </Group>
    </form>
  );
}

И вот пример, как формы используются в Steroids:

import {login} from '@steroidsjs/core/actions/auth';
import {ROUTE_USERS} from 'routes';

const FORM_ID = 'LoginFrom';

export default function LoginFrom() {

    return (
        <div className={bem.block()}>
            <Form
                formId={FORM_ID}
                fields={formFields}
                action='/api/v1/auth/login'
                actionMethod='POST'
                useRedux
                onComplete={(values, data) => {
                    if (data.accessToken) {
                        dispatch(login(data.accessToken, ROUTE_USERS));
                    }
                }}
                submitLabel='Войти'
            />
        </div>
    );
}

В этом примере реализована даже логика отправки данных формы на конкретный API endpoint. У Form также есть такие пропсы, как onBeforeSubmit, onAfterSubmit, onComplete, которые вызывают функции соответственно до отправки формы, после отправки и в случае успешного выполнения запроса. Еще есть пропсы для сохранения данных формы в редаксе (useRedux), в адресной строке (addressBar) и в local storage (autoSave). Вообще компонент Form в Steroids довольно функциональный. О нем будет одна из следующих статей.

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

Вот пример, как используется List c пагинацией:

<List
   listId='FlightList'
   items={flightItems}
   itemView={ListCard}
   itemProps={{
      bem,
   }}
   contentClassName={bem.element('list')}
   paginationSize={{
      defaultValue: 2,
      sizes: [1, 2, 3],
   }}
   pagination={{
      defaultValue: 3,
   }}
/>

Теперь давайте сравним степень кастомизации компонентов в разных библиотеках. Везде поддерживается кастомизация через различные пропсы для стилей (в каждой библиотеке это будут свои) и через переопределение css-переменных. Библиотека Mantine также предоставляет возможность использовать ее как headless ui-библиотеку, что значит использовать только логику (core-часть), а стили добавлять свои. В Steroids есть возможность переопределять полностью view-часть компонента. Это ещё более глубокая степень кастомизации. Подобный функционал мы встречали только в одной библиотеке — Korus UI от Сбера. Там есть возможность передать view-часть через пропсы, но нет возможности переопределить ее для всех компонентов в проекте (например, для всех InputField).

И напоследок сравним библиотеки по наличию активного сообщества. Этот критерий тоже имеет вес при выборе ui-библиотеки для проекта. У трех из пяти библиотек есть сообщество разработчиков, которое занимается  поддержкой, развитием и фиксом багов. А именно у Material UI, Mantine и Steroids.

Какую библиотеку выбрать, конечно, стоит решать в каждом проекте отдельно, так как везде требуется разный функционал. Мы сравнили всего лишь несколько библиотек из тех, что пользуются популярностью у разработчиков, но их существует ещё довольно много.

И в заключение

Изначально фреймворк Steroids не создавался как покоритель всего, но за 8 лет вырос в полноценный продукт.

В 2022 году мы выиграли грант от faise на его развитие. В рамках работ по гранту было реализовано много новых ui-компонентов, а также несколько комплексных компонентов. Мы провели рефакторинг кода, покрыли фреймворк тестами на 70%, написали подробную документацию и запустили сайт с большим набором демоверсий компонентов.

Если вас заинтересовал фреймворк Steroids и вы хотите узнать о нем больше, то вот ссылка на документацию и быстрый старт

Спасибо за внимание)

Комментарии (23)


  1. nihil-pro
    15.07.2025 06:58

    Шо, опять?


  1. markelov69
    15.07.2025 06:58

    Фреймворк Steroids подходит для создания полноценного SPA приложения с продуманной архитектурой

    управление состоянием, в том числе с использованием Redux, React Context;

    Вы сделали 11 ошибок в слове плохой. Вместо SPA приложения с плохой архитектурой, вы по ошибке написали с продуманной.

    Очнитесь, все адекватные люди последние 9 лет используют MobX в связке с React. В противном случае это просто очередной говнокод.
    React нужно использовать по назначению, рендер html и жизненный цикл компонента, а управление состоянием, как глобальным, так и локальным - MobX.


    1. gunGarave
      15.07.2025 06:58

      Осильте уже что-то сложнее MobX. Внезапно будет и Redux не плох, если применять его к месту и руками.


      1. SWATOPLUS
        15.07.2025 06:58

        Я использую RxJS и Inversify в связке с react и это работает. А Redux, это просто очень много размазанного по системе бойлерплейта. Может быть я чего-то не понимаю, но для меня дебажить и писать новые фичи с Redux сложнее и дольше.

        RxJS + Inversify позволяет хранить структуру данных вместе с методами их обработки. Соблюдается принцип high cohesion. Я вижу в одном месте связанные логически вещи и инкапсулирую состояние. Появляется иерархия сервисов. От простых для работы с localstorage, до сложных бизнес сценариев (например многошаговые формы, я могу создать сервис для всех этапов, и сервисы для конкретного шага, что позволяет выстроить нормальные и слабозависимые друг от друга шаги и отдать их разным разработчикам).


        1. clerik_r
          15.07.2025 06:58

          Я использую RxJS и Inversify в связке с react

          В принципе если машину толкать руками она тоже будет ехать (это RxJS и Inversify), только вопрос зачем?) Когда можно заправить ее бензином и завести (это MobX).

          RxJS + Inversify позволяет хранить структуру данных вместе с методами их обработки.

          Прикольно) MobX тоже) Как бы by design) Ну и так далее по тексту) Он покрывает все кейсы которые только захотите реализовать, с 0 оверхедом по коду и с максимально возможной читаемостью и понятностью кода. Ибо по сути он тупо нативный.


          1. SWATOPLUS
            15.07.2025 06:58

            Лично мне кажется, что так больше контроля на потоком данных и соблюдается принципы low coupling и high cohesion. Ну вот как-то по субъективным ощущениям это работает луше.


            1. clerik_r
              15.07.2025 06:58

              Лично мне кажется, что так больше контроля на потоком данных и

              Вам кажется. Больше контроля быть не может априори, ибо ровно ноль ограничений накладывает MobX.

              соблюдается принципы low coupling и high cohesion

              Хоспадя, что за новая мода пошла, увидели low coupling и high cohesion, теперь из каждого утюга о них поют. Жаль только с реальной жизнью всё это не контачит. Так что забудьте про эти глупости. Самое главное о чем стоить думать это KISS(Keep it simple stupid), а всё остальное второстепенно. Ну и принципы с MobX можно соблюдать какие душе угодно, всё по той же причине, отсутствие ограничений.

              А вот с RxJS только write only once вырви глаз код, который поддерживать без слёз нереально можно соблюдать.

              Ну вот как-то по субъективным ощущениям это работает лучше.

              Это вам точно кажется)


        1. gunGarave
          15.07.2025 06:58

          Я использовал как MobX, так и Redux. И ещё кучу менеджеров состояний. И мне было всегда удобно, не превращался код в кашу. Что я делаю не так? Как закривить руки, чтобы прямо в кашу?


          1. clerik_r
            15.07.2025 06:58

            Я использовал как MobX, так и Redux. И ещё кучу менеджеров состояний. 

            Я тоже.

            И мне было всегда удобно, не превращался код в кашу

            Ага, а я живу на Марсе. Разница в коде и в том, как принято его писать используя Redux и Mobx просто колоссальная, это вообще небо и земля.

            Что я делаю не так? Как закривить руки, чтобы прямо в кашу?

            Всё просто, вы либо на самом деле не работали на проектах где есть redux и т.п., либо дальше Hello world ваши проекты не уходили. Потому что только тот кто реально не работал с redux и mobx не видит разницу. а уж тем более тот, кто говорит что проект где redux это не говнокод с кашей, так он вообще в принципе не работал на проекте с redux. Либо его представления о хорошем коде диаметрально противоположны хорошему коду, поэтому эта каша и говнокод не кажется кашей и говнокодом.

            Плюс у вас написано, что вы Fullstack-программист, а front-end. Это тоже объясняет ваш ход мыслей.


      1. SergTsumbal
        15.07.2025 06:58

        Зачем? KISS, Keep It Simple, Stupid


        1. clerik_r
          15.07.2025 06:58

          KISS, Keep It Simple, Stupid

          Вот вот, это самый главный и важный принцип в разработке любого ПО.


      1. clerik_r
        15.07.2025 06:58

        Осильте уже что-то сложнее MobX

        Зачем? А главное нафига?) Что-бы что? Нет ни одного кейса, где применение Redux и т.п. будет лучше, чем MobX. Уж тем более с точки зрения красоты, читаемости и понятности кода.


    1. isumix
      15.07.2025 06:58

      вы прямо Фьюзор описали

      рендер html и жизненный цикл компонента, а управление состоянием, как глобальным, так и локальным - MobX

      только в нем можно любой стейт менеджер подключить на пропсу { mount }

      ну и раз нет состояния - то становится не нужен ре-рендеринг и хуки, жизненный цикл компонента сжимется в 4 состояния: create, mount, update, unmount


    1. DmitryOlkhovoi
      15.07.2025 06:58

      Очнитесь, все адекватные люди последние 9 лет используют MobX в связке с React.

      Адекватные люди имеют это из коробки со Vue


  1. xadd
    15.07.2025 06:58

    Опять тут навязывают всякие структуры, чтобы говнокод случайно не написали, сделайте просто, чтобы собиралось без геморроя и без всяких топорных /app & /pages


    1. affka
      15.07.2025 06:58

      Структуры никто не навязывает, но есть описание и примеры как можно делать (и которые мы у себя используем как правила). Но привязки к директориям (app & /pages ...) здесь нет

      upd: и да, если не дать примера как делать — будут делать говнокод :) Либо прогеры будут крутые, но каждый напишет по своему.. и опять получится говнокод)


      1. xadd
        15.07.2025 06:58

        А, ну тогда совсем хорошо


  1. HELL_4IRE
    15.07.2025 06:58

    Нафига redux/rtk когда есть Zustand


    1. clerik_r
      15.07.2025 06:58

      Нафига redux/rtk когда есть Zustand

      Zustand - полу мера, да он немного получше redux/rtk, но ему далеко до MobX. А какой смыл использовать ни рыбу ни мясо, когда можно взять отличный инструмент и не страдать.


      1. DmitryOlkhovoi
        15.07.2025 06:58

        отличный инструмент и не страдать

        при этом вы продолжаете использовать react)))


        1. clerik_r
          15.07.2025 06:58

          при этом вы продолжаете использовать react)))

          Так React доставляет мне ровно 0 неудобств, только даёт плюсы, а удобнее JSX'a пока ничего не придумали. Я же его использую по назначению, как view. Для всего остального есть MobX) Поэтому мне и без разницы какой версией реакта пользоваться, 16, 17, 18, 19, 20, ..100 ) Всё что нужно для полноценной разработки любого приложения есть в 16 версии. Почему именно 16? Просто потому что useEffect удобнее чем componentDidMount, componentDidUpdate, componentWillUnmount. А аналог constructor это useState(() => {...})


          1. DmitryOlkhovoi
            15.07.2025 06:58

            Посмотрите ради интереса alpine, vue, svelte... Я после таких тулов, на проектах с реакт, как будто ем костлявую рыбу)) Не говоря уже о фундаментально устаревших вещах как virtual dom

            Просто потому что useEffect 

            ну вот тут оно же)) люди живут без этого)


            1. clerik_r
              15.07.2025 06:58

              Посмотрите ради интереса alpine, vue, svelte... Я после таких тулов, на проектах с реакт, как будто ем костлявую рыбу)

              Я всё это видел много лет назад, и vue 2 и vue 3, и svelte и angular и inferno и т.д. и т.п.. Что только я не видел за последние 13 лет. И пробовал создавать проекты на них. Но react + mobx по сей день максимально удобны для разработки.

              Не говоря уже о фундаментально устаревших вещах как virtual dom

              Дайте мне копию синтаксиса React и MobX, а под капотом не будет virtual dom, да и на самом деле пофигу что там под капотом, если по реальным замерам оно будет реально работать быстрее, есть меньше памяти и т.п. То я сразу же на это пересяду без задних мыслей) Но увы, такого пока нет) А самому писать лень, ибо и так всё более чем устраивает мои потребности)

              ну вот тут оно же)) люди живут без этого)

              Я в своё время реализовывал его и для классовых компонентов, это легко

              export class MyComponent extends BaseComponent {
                constructor() {
                  this.useEfftct(() => {...});
                  this.useEfftct(() => {...}, () => [this.props.name]);
                }
              }