Когда метод объекта передаётся как колбэк, он теряет контекст (см. фото). После клика в консоли будет undefined.
this зависит от способа вызова функции, а не от места, где она объявлена.
При передаче метода как ссылки (btn.handleClick) контекст теряется — this больше не указывает на объект.
1. Явно привязать контекст
button.addEventListener('click', btn.handleClick.bind(btn));
2. Использовать стрелочную функцию
button.addEventListener('click', () => btn.handleClick());
#hotfix #js
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰6❤3👍3
Кажется, простой счётчик — но React со своим batching (см. на картинке).
Ждём
React группирует (batch) обновления состояния внутри одного события. Обе строки читают старое значение count из замыкания, поэтому результат — 1.
Если новое состояние зависит от предыдущего — используйте функциональное обновление
setCount(prev => prev + 1);
setCount(prev => prev + 1);
Теперь результат будет 2.
React работает по снимкам состояния, а не по «живым» переменным — и именно это часто сбивает с толку.
#hotfix #react
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰6👍3
Классика: делаешь height: 100vh для фуллскрин-секции, на десктопе всё ок, а на телефоне контент уезжает за экран и появляется скролл.
Браузер считает 100vh по полной высоте экрана, включая скрывающиеся панели. Когда скроллишь — адресная строка прячется, высота viewport меняется, и блок начинает прыгать.
Раньше приходилось считать реальную высоту через JS — решение рабочее, но костыль.
dvh — динамическая высота, подстраивается при скролле
svh — учитывает адресную строку
lvh — без адресной строки, максимальная высота
Поддержка: iOS 15.4+, Chrome 108+, Safari 15.4+
Сначала указываем height: 100vh, а следом height: 100dvh — новые браузеры просто переопределят старое значение.
#hotfix #css
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18🥰5❤🔥4❤1
Передаём user через Dashboard и Sidebar, хотя они его не используют. Компоненты становятся «курьерами» для чужих данных.
Используйте композицию через children — передавай данные напрямую туда, где они нужны.
Что это даёт:
Когда что использовать:
#hotfix #react
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍3❤2👏1
😓 Роутинг в SPA — боль
Классика: слушаем click, ставим preventDefault(), делаем history.pushState(), потом ловим popstate и рендерим контент.
Работает, но это куча бойлерплейта и расхождений между состоянием, URL и историей.
❔ Почему так:
History API не создавался под SPA. Он не умеет централизованно управлять всеми типами навигации и не даёт понять, когда переход «завершён», чтобы безопасно менять UI и скролл.
🔤 Нормальное решение — Navigation API (эксперимент, Chrome 102+):
✅ Fallback:
Если window.navigation нет, остаёмся на старом pushState.
📦 Поддержка:
Chromium 102+, Safari (новые версии), Firefox — пока нет.
API экспериментальный, используйте feature-detect.
📎 Официальная спецификация
🐸 Библиотека фронтендера
#hotfix #js
Классика: слушаем click, ставим preventDefault(), делаем history.pushState(), потом ловим popstate и рендерим контент.
Работает, но это куча бойлерплейта и расхождений между состоянием, URL и историей.
History API не создавался под SPA. Он не умеет централизованно управлять всеми типами навигации и не даёт понять, когда переход «завершён», чтобы безопасно менять UI и скролл.
• navigate — единое событие для всех переходов
• event.intercept() — перехват и свой обработчик (загрузили данные, отрисовали, проверили доступ)
• event.scroll() — нативный скролл
• { committed, finished } — когда менять URL и когда переход реально завершён
• entries() и currentEntry — история как нормальные объекты со state
Если window.navigation нет, остаёмся на старом pushState.
if ('navigation' in window) {
navigation.addEventListener('navigate', (event) => {
if (shouldNotIntercept(event)) return;
const url = new URL(event.destination.url);
event.intercept({
async handler() {
renderSkeleton();
const html = await fetchPage(url.pathname);
render(html);
event.scroll();
},
});
});
const { committed, finished } = navigation.navigate('/profile');
committed.then(() => showLoading());
finished.finally(() => hideLoading());
}
📦 Поддержка:
Chromium 102+, Safari (новые версии), Firefox — пока нет.
API экспериментальный, используйте feature-detect.
#hotfix #js
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰5❤3🔥1