Обновить
64K+

ReactJS *

JavaScript-библиотека для создания интерфейсов

23,39
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности
Формат публикации

Пишешь JSX, рисует Rust: от куба до мультика на raea

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели5.7K

Сцену пишешь на React, а кадр рисует игровой движок Bevy на Rust, без браузера. Так устроен raea, который вышел 9 ноября. Я проследил путь прыгающего куба от JSX до движка и нашёл внутри обычный div. А потом поручил Claude Code снять человека с кофе: тот доехал до стола как на конвейере, а чашка упала раньше, чем он до неё дотянулся.

Читать далее

От localStorage Next.js к cloud favorites, Supabase Auth, RLS и миграция без потери гостевого UX

Время на прочтение12 мин
Охват и читатели7.9K

Избранное можно поместить в localStorage. Пользователь нажимает кнопку, приложение сохраняет ID записи в браузере, отдельный backend для этого не нужен. Проблема появляется после добавления аккаунтов. localStorage привязан к конкретному браузеру. После входа с другого устройства сохранённого списка там нет. Простая замена localStorage на облачную таблицу тоже меняет поведение продукта, теперь для кнопки «В избранное» приходится сначала требовать авторизацию. Если гостевой режим уже работает, логичнее сохранить его и переключать источник данных после входа.
В EventMap схема выглядит так:

Читать далее

Как считать просмотры, если контент меняется прямо на экране

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели7.3K

Привет, Хабр! Я Самсон Авакян, фронтенд-разработчик команды Т-Путешествий в Т-Банке. Расскажу, как мы собираем просмотры офферов для обучения ML-модели ценообразования, когда цена и условия в карточках меняются прямо на экране.

Делюсь решением на React и TypeScript с использованием Intersection Observer.

А еще моя статья — часть проекта «20 в 20», в котором мы рассказываем о жизни наших ИТ-хабов. Из моего выпуска вы узнаете о южных, ростовских традициях. 

Читать далее

Как я на 4-й день пентеста чуть не принял 500-ку за RCE

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели8.7K

Здравствуйте, дорогие читатели! Это моя первая и надеюсь, что не последняя, публикация на Habr. Буду очень рад возможной конструктивной критике и обратной связи. Эта статья стала итогом моего первого раунда реального пентестирования на живом сайте, поэтому спешу поделиться опытом. Раньше занимался только разработкой, поэтому это был крайне интересным опытом. Людям, которые только хотят вливаться в пентестирование или идти в него из разработки, как я, эта статья может быть крайне полезна. А более профессиональные пентестеры и программисты, возможно, смогут чутка похихикать с неё и узнать себя в начале карьерного пути. В общем, надеюсь, что статья не оставит вас равнодушной. Не буду тянуть и приятного прочтения!

TL;DR. Теперь кратко и по делу. Нашёл на одном сайте (легально, с разрешения владельца, само собой) 500-ю ошибку от одного HTTP‑заголовка. Сначала подумал — баг десериализации, может, RCE. Потом сел, собрал стенд, намерил — и находка усохла до аккуратного «500 вместо 400». По дороге я один раз испугался, что уронил чужой прод (оказалось — перепутал окна терминала). В общем, я заспойлерил всё в самом начале, но история от этого, надеюсь, вышла не менее интересная.

Читать далее

OpenAPI спецификация как инструмент frontend-разработчика: практическое применение и типичные проблемы

Уровень сложностиСредний
Время на прочтение20 мин
Охват и читатели5.4K

OpenAPI — это не только Swagger UI с описанием ручек. Спецификация может стать основой для множества повседневных задач фронтенд-разработчика:

Генерации TypeScript-типов для RTK Query, React Query и нативного fetch.

Генерации API-клиентов на примере orval.

Типизации запросов и ответов в BFF на Express.

Валидации запросов в обработчиках Express.

Генерации моковых данных и запуска mock-сервера.

Но что делать, если исходная спецификация содержит ошибки и всё это перестаёт работать? Здесь пригодятся валидация и подготовка спецификации — покажу, как хранить необходимые исправления в виде воспроизводимых правил с помощью openapi-modifier.

Читать далее

Как защитить статус оплаты в React от запоздалых ответов

Время на прочтение4 мин
Охват и читатели7K

Пользователь уже оплатил подписку, но React снова показывает «Ожидаем оплату». Оба запроса вернули HTTP 200 — просто старый ответ пришёл последним. Разберём, как воспроизвести эту гонку и не дать запоздалому ответу перезаписать актуальный статус заказа.

Читать далее

Путь от импорта синглтонов до DI на коленке через React Context

Время на прочтение7 мин
Охват и читатели7K

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

Все эти три способа очень похожи и приводят нас к одинаковым проблемам. В статье разберём их и поговорим о том, почему «дикие» глобальные синглтоны в React — это антипаттерн, и пошагово пройдём путь эволюции архитектуры от простых хуков до предсказуемого DI на React Context.

Читать далее

Кривой TypeScript тип выжрал 15 гигов оперативы

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели11K

VSCode перестал показывать типы, автокомплит умер, а ноутбук начал пожирать всю оперативку. Под подозрением были расширения, антивирус и корпоративное ПО. Но после нескольких перезагрузок и часов расследования выяснилось, что виновником оказался всего один криво описанный тип в TypeScript, который запускал десятки зависших Node.js-процессов.

Читать далее

Файлы из браузера в браузер и «торрент» без установки: как устроен TFile.io

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели6.7K

Привет, Хабр! Я делаю TFile — сервис, который передаёт файлы напрямую между браузерами. Без регистрации, без установки, без загрузки файла на чей-то сервер. Расскажу, как он устроен и на какие грабли я наступил по дороге. Цифры в статье — из реальных замеров.

Два режима

⚡ Отправить сейчас. Открываете сайт, получаете ссылку вида tfile.io или QR-код. Второй человек открывает её, и дальше можно перетаскивать файлы, целые папки, текст и скриншоты из буфера обмена.

🔗 Поделиться позже. Выбираете файлы и получаете ссылку. Любой, кто её откроет, видит список и скачивает то, что ему нужно, когда ему удобно. Те, кто уже скачал, раздают куски дальше — как в торренте, только прямо в браузере.

Как идут байты

Сервер у TFile только сигнальный: небольшой WebSocket на Node.js, через который два браузера обмениваются SDP и ICE-кандидатами. Сами файлы идут по WebRTC data channel, а он всегда зашифрован (DTLS). Если прямое соединение не получается (строгий NAT, корпоративная сеть), трафик идёт через TURN-сервер (eturnal). Ему достаются уже зашифрованные данные: прочитать их он не может и ничего не хранит.

Чтобы было видно, что сервер не встал посередине, оба участника видят код безопасности: SHA-256 от DTLS-отпечатков обоих SDP, 40 бит, которые показываются как 12 цифр. Совпадают коды — сертификаты никто не подменял.

Грабли: SCTP и большие очереди

Первая версия просто писала в канал, пока bufferedAmount не дойдёт до 4 МБ. На loopback в Chrome оказалось, что SCTP отправляет всё накопленное разом: пачка около 2 МБ теряет пакеты, и передача стоит 2–3 секунды.

Читать далее

Как React не даёт несрочному рендеру потеряться: startTransition, useDeferredValue и Suspense

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели5.8K

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

Но что, если пользователь печатает без остановки: список не обновится никогда? И что видит пользователь, пока новый список считается или грузится с сервера, - старый список, пустой экран или спиннер?

Читать далее

Один hero-блок, три файла: проверяю установку UI через shadcn в отдельный проект

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели4.1K

Устанавливаю один hero-блок через production-registry shadcn в отдельный Next.js-проект. Разбираю три полученных файла, адаптацию через пропсы и проверки на ширинах от 320 до 1280 px. Один реальный опыт с кодом, замерами и ограничениями.

Посмотреть эксперимент

Какая нейронка лучше подходит для фронтенда? Сразу скажу, что ответа тут не будет, тут я сам хотел узнать мнение...

Охват и читатели6.6K

Какая нейронка лучше подходит для фронтенда?

Сразу скажу, что ответа тут не будет, тут я сам хотел узнать мнение коллег, так как не нашел релевантной информации на этот счёт.

Читать дальше →

Почему React Server Components интегрируются с bundler

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели7.6K

Привет, я фронтенд-разработчик, и сегодня хочу разобраться с одной интересной особенностью React Server Components.

Если вы работали с RSC, то наверняка замечали, что вокруг них почти всегда появляется ещё один участник — bundler. В документации React прямо говорится, что директивы вроде 'use client' дают инструкции bundler'ам, совместимым с RSC, а при встрече клиентского компонента bundler должен построить для него клиентскую сборку.

Но возникает вполне логичный вопрос. Зачем React Server Components вообще нужен bundler?

Ведь JavaScript уже умеет работать с модулями. Браузер понимает import, умеет загружать ES-модули и поддерживает динамический import().

На первый взгляд можно сделать всё достаточно просто.

Читать далее

Ближайшие события

SEO для сайтов на Next.js: почему страницы не попадают в индекс и что не видят Яндекс и Google

Время на прочтение10 мин
Охват и читатели7.6K

Я веду несколько сайтов на Next.js, и по рабочим журналам на них чаще всего повторяются четыре SEO ошибки: полная копия сайта на www, код 200 вместо 404 на несуществующих адресах, теги title и canonical не там, где их ждет робот, и лишние параметры в адресах.

Читать далее

Почему setTimeout в React видит старое значение state Введите в поле «Первый», нажмите кнопку, а затем, пока таймер не...

Охват и читатели3.1K

Почему setTimeout в React видит старое значение state

Введите в поле «Первый», нажмите кнопку, а затем, пока таймер не сработал, замените текст на «Второй»:

Читать дальше →

React Context без лишних ререндеров: подписка на отдельные поля

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели7.9K

Знакомая ситуация: в контексте лежат два поля, скажем, name и age. Меняется age, и ререндерится компонент, который читает только name. У useContext нет селектора, как у useSelector в Redux: React сравнивает value провайдера целиком, а при каждом изменении это новый объект. Ни useMemo, ни React.memo тут не спасают.

В статье — небольшой контекст, где компонент ререндерится, только когда меняется его собственное поле. И разбор, почему он устроен именно так:

Почему через контекст стоит передавать не сами данные, а стабильный объект доступа к ним?

Почему обычные приёмы — useMemo на value и раздельные контексты — до этого не дотягивают?

Зачем для подписки нужен useSyncExternalStore и что такое tearing?

На каких деталях легко ошибиться и когда такой контекст вообще нужен?

Читать далее

React 19: почему return { error } не предотвращает очистку формы Форма показывает ошибку сохранения, но введённый...

Охват и читатели3K

React 19: почему return { error } не предотвращает очистку формы

Форма показывает ошибку сохранения, но введённый текст уже исчез. Такое возможно при использовании функции в action: после её нормального завершения React сбрасывает неконтролируемые поля.

Минимальный пример без сервера — обработчик намеренно всегда возвращает ошибку:

Читать дальше →

Quill в Next.js App Router, editor, autosave и HTML viewer с подсветкой кода

Время на прочтение10 мин
Охват и читатели5.5K

WYSIWYG-редактор в Next.js App Router затрагивает несколько слоев приложения. Quill работает с DOM и browser API, поэтому сам редактор живет на клиенте. Контент нужно хранить отдельно от экземпляра Quill, передавать в компонент при смене сущности, сохранять на сервер и затем показывать без toolbar и режима редактирования.
Если хранить результат Quill как HTML, редактор и viewer могут работать с одной строкой contentHtml. Editor меняет HTML через onChange. Autosave отправляет новую версию после паузы во вводе. Viewer получает сохраненный HTML и отдельно обрабатывает элементы, которые Quill использует для code blocks. Для подсветки кода добавляется highlight.js.

Читать далее

Как React прерывает рендер: конкурентный рендеринг изнутри

Уровень сложностиСложный
Время на прочтение21 мин
Охват и читатели4.5K

Начиная с React 18 рендер можно прервать: срочные обновления обгоняют несрочные, даже если React уже взялся за несрочное. Если задуматься, вопросов много:

Как React посреди рендера отдаёт поток браузеру, чтобы тот обработал ввод, а потом продолжает с того же места?

Почему до React 16 он так не умел?

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

Что происходит с незакоммиченными обновлениями, когда пришло что-то срочное?

И главное, как обновления, которые выстраиваются в очередь, не путаются в порядке, если срочное пришло позже, но должно обогнать несрочные?

Читать далее

Удалили строку в React, а её заметка осталась у другого пользователя Представим: в списке два человека, у каждого поле...

Охват и читатели2.3K

Удалили строку в React, а её заметка осталась у другого пользователя

Представим: в списке два человека, у каждого поле для заметки. Вводим «Позвонить вечером» рядом с Анной, удаляем Анну — и видим ту же заметку у Бориса.

Данные людей не перепутаны. Проблема в том, как React сопоставляет строки между рендерами.

Вот компонент, в котором ошибку можно воспроизвести:

Читать дальше →
1
23 ...