В проектах часто встречается рендер через логический оператор И:
Если
А что если мы хотим вывести компонент при одном из условий?
Можно написать так:
Но тут есть какой-то подвох... Он не всегда бросается в глаза.
Из-за приоритета операторов И(
Поэтому этот код на самом деле работает так:
В результате компонент появится только тогда, когда
Чтобы логика работала правильно, достаточно добавить группировку:
Теперь компонент отрендерится, если хотя бы одно условие истинно.
Но на самом деле можно упростить ещё больше. Я уже писал про условный рендер в этом посте(тык). Он выглядит понятнее и не заставляет задумываться о приоритетах:
Так код читается сразу и не заставляет думать лишний раз.
#BestPractices #JavaScript
{condition && <div>Component</div>}
Если
condition истинно, то отрендерится компонент. Если же условие ложно, то мы ничего не увидим. Причину этого мы разбирали в этом посте(клац).А что если мы хотим вывести компонент при одном из условий?
Можно написать так:
{condition || secondCondition && <div>Component</div>}
Но тут есть какой-то подвох... Он не всегда бросается в глаза.
Из-за приоритета операторов И(
&&) выполняется раньше, чем ИЛИ(||). Поэтому этот код на самом деле работает так:
{condition || (secondCondition && <div>Component</div>)}
В результате компонент появится только тогда, когда
condition ложно, а secondCondition истинно.Чтобы логика работала правильно, достаточно добавить группировку:
{(condition || secondCondition) && <div>Component</div>}
Теперь компонент отрендерится, если хотя бы одно условие истинно.
Но на самом деле можно упростить ещё больше. Я уже писал про условный рендер в этом посте(тык). Он выглядит понятнее и не заставляет задумываться о приоритетах:
{condition || secondCondition ? <div>Component</div> : null}
Так код читается сразу и не заставляет думать лишний раз.
#BestPractices #JavaScript
⚡7👍5
Привет! Сегодня разберём метод
Что он делает?
Этот метод создаёт промис и возвращает объект, содержащий сам промис и функции для его разрешения или отклонения.
Синтаксис:
-
-
-
Теперь можно вызывать
Пример:
Допустим, вы ждёте событие от внешнего API
Раньше писали так:
Преимущества withResolvers:
1. Упрощает создание управляемых промисов.
2. Убирает антипаттерн ручного присваивания.
3. Делает код более читаемым и безопасным.
Поддержку смотрите через Can I Use.
#JavaScript #BestPractices
Promise.withResolvers. Он упрощает работу с промисами, особенно когда нужно управлять их состоянием извне.Что он делает?
Этот метод создаёт промис и возвращает объект, содержащий сам промис и функции для его разрешения или отклонения.
Синтаксис:
const { promise, resolve, reject } = Promise.withResolvers();
-
promise — сам промис.-
resolve(value) — функция для успешного завершения промиса.-
reject(reason) — функция для отклонения промиса.Теперь можно вызывать
resolve(data) или reject(error) в любом месте, и промис перейдёт в соответствующее состояние.Пример:
Допустим, вы ждёте событие от внешнего API
const { promise, resolve, reject } = Promise.withResolvers();
const ws = new WebSocket('wss://example.com');
ws.onmessage = event => resolve(event.data);
ws.onerror = error => reject(error);
promise
.then(data => console.log('Получено:', data))
.catch(error => console.error('Ошибка:', error));
Раньше писали так:
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
Преимущества withResolvers:
1. Упрощает создание управляемых промисов.
2. Убирает антипаттерн ручного присваивания.
3. Делает код более читаемым и безопасным.
Поддержку смотрите через Can I Use.
#JavaScript #BestPractices
⚡7👍6
Привет! Сегодня разберём интересный момент в React с вызовом нескольких
Вопрос
Что выведет консоль, и сколько раз сработает useEffect?
Разбор
1. Все три вызова
2. React батчит вызовы
3.
Вывод в консоль:
Чтобы каждый вызов
Теперь каждый вызов
#react
setState в одном обработчике.
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Effect:", count);
}, [count]);
const handleClick = () => {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>+3</button>
</div>
);
}
Вопрос
Что выведет консоль, и сколько раз сработает useEffect?
Разбор
1. Все три вызова
setCount используют одно и то же значение count, так как React не обновляет состояние мгновенно.2. React батчит вызовы
setState в одном событии. В итоге React применяет только последний вызов, и count становится 1.3.
useEffect срабатывает один раз, так как состояние изменилось только один раз.Вывод в консоль:
Effect: 1Чтобы каждый вызов
setCount учитывал предыдущее состояние, используйте функциональное обновление:
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Effect:", count);
}, [count]);
const handleClick = () => {
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>+3</button>
</div>
);
}
Теперь каждый вызов
setCount получает актуальное значение prev, и count увеличивается правильно, но useEffect всё равно сработает один раз, так как React батчит изменения.#react
🔥8👍5
Сегодня разберём CSS-свойство —
Что такое display: contents?
Это свойство заставляет элемент "исчезнуть" из рендера, но его дочерние элементы остаются и ведут себя так, будто родителя нет.
Пример
У нас есть сетка, но лишняя обёртка ломает структуру:
Без
Когда полезно?
- Убираем лишние обёртки, не ломая семантику HTML.
- Упрощаем работу с Grid и Flexbox, чтобы дети родителя участвовали в сетке напрямую.
- Используем для улучшения доступности.
Поддержка браузерами: Can I Use
#CSS #HTML
display: contents. Оно редко встречается, но может сильно упростить вёрстку в некоторых кейсах.Что такое display: contents?
Это свойство заставляет элемент "исчезнуть" из рендера, но его дочерние элементы остаются и ведут себя так, будто родителя нет.
Пример
У нас есть сетка, но лишняя обёртка ломает структуру:
<style>
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.inner {
display: contents;
}
p {
background: lightblue;
padding: 10px;
}
</style>
<div class="wrapper">
<div class="inner">
<p>Привет</p>
<p>Мир</p>
</div>
</div>
Без
display: contents блок .inner создаёт лишний уровень в сетке, и не попадают в ячейки .wrapper. С display: contents элемент .inner исчезает из рендера, и <p/> становятся прямыми детьми .wrapper для сетки, занимая ячейки.Когда полезно?
- Убираем лишние обёртки, не ломая семантику HTML.
- Упрощаем работу с Grid и Flexbox, чтобы дети родителя участвовали в сетке напрямую.
- Используем для улучшения доступности.
Поддержка браузерами: Can I Use
#CSS #HTML
⚡8👍5🔥3
Вы пользовались ИИ-редакторами? 🤯
Я недавно попробовал вайбкодить домашние проекты и это просто какой-то шок. Раньше на MVP уходило несколько дней, а сейчас буквально 1–2 часа на фронт и бэк. Главное написать качественный промт, с которым тоже помогает ИИ😱
Да, это чаще всего платно и нередко говнокодит, но если брать такой код за основу, то реально можно ускорить разработку. Многое ещё зависит от модели, но все они довольно часто допускают тупые ошибки и потом по кругу пытаются их исправить.
Как бы грустно это ни звучало, но зима близко🥶 Конечно, сложно будет заменить программистов из-за качества сгенереного кода, поддержки и в целом понимания продукта, но со временем определённо станет сложнее искать работу(пока выдыхаем) 😕
#career #frontend
Я недавно попробовал вайбкодить домашние проекты и это просто какой-то шок. Раньше на MVP уходило несколько дней, а сейчас буквально 1–2 часа на фронт и бэк. Главное написать качественный промт, с которым тоже помогает ИИ
Да, это чаще всего платно и нередко говнокодит, но если брать такой код за основу, то реально можно ускорить разработку. Многое ещё зависит от модели, но все они довольно часто допускают тупые ошибки и потом по кругу пытаются их исправить.
Как бы грустно это ни звучало, но зима близко
#career #frontend
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔7👍3👏2🔥1
Заканчиваем серии постов про SOLID! Сегодня разберём последнюю букву - D, которая расшифровывается как Dependency Inversion Principle (Принцип инверсии зависимостей).
О чём этот принцип?
Высокоуровневые модули не должны зависеть от низкоуровневых. Оба должны зависеть от абстракций. А абстракции не должны зависеть от деталей — детали зависят от абстракций.
Если проще - зависите от интерфейсов, а не от конкретных классов. Это делает код гибким и независимым от деталей реализации.
Пример плохого подхода:
Как улучшить?
Введём интерфейс и передадим зависимость через конструктор:
Теперь
Что это даёт?
- Легко менять реализацию (база, файл, API) без правок в сервисе.
- Подставляйте моки для тестов.
- Зависимости явные, меньше связей.
#BestPractices #JavaScript #typescript
О чём этот принцип?
Высокоуровневые модули не должны зависеть от низкоуровневых. Оба должны зависеть от абстракций. А абстракции не должны зависеть от деталей — детали зависят от абстракций.
Если проще - зависите от интерфейсов, а не от конкретных классов. Это делает код гибким и независимым от деталей реализации.
Пример плохого подхода:
class Database {
save(data: string): void {
console.log(`Сохранено в базе: ${data}`);
}
}
class UserService {
private db = new Database();
saveUser(user: string): void {
this.db.save(user);
}
}
const service = new UserService();
service.saveUser("Alice"); // Сохранено в базе: Alice
UserService жёстко привязан к Database. Хотите сохранить данные в файл или API? Придётся переписывать UserService.Как улучшить?
Введём интерфейс и передадим зависимость через конструктор:
interface Storage {
save(data: string): void;
}
class Database implements Storage {
save(data: string): void {
console.log(`Сохранено в базе: ${data}`);
}
}
class FileStorage implements Storage {
save(data: string): void {
console.log(`Сохранено в файл: ${data}`);
}
}
class UserService {
constructor(private storage: Storage) {}
saveUser(user: string): void {
this.storage.save(user);
}
}
const dbService = new UserService(new Database());
dbService.saveUser("Alice"); // Сохранено в базе: Alice
const fileService = new UserService(new FileStorage());
fileService.saveUser("Bob"); // Сохранено в файл: Bob
Теперь
UserService зависит от абстракции Storage.Что это даёт?
- Легко менять реализацию (база, файл, API) без правок в сервисе.
- Подставляйте моки для тестов.
- Зависимости явные, меньше связей.
#BestPractices #JavaScript #typescript
🔥10👍6
Привет! Недавно мы разбирали нативный метод
Задача
Дан массив объектов:
Нужно сгруппировать по возрасту:
Решение через
Как работает?
1.
2. Для каждого item вычисляем ключ через
3. Если ключа нет в
4. Добавляем
5. Возвращаем обновлённый
#JavaScript #interview
Object.groupBy, а сегодня разберём задачу с реализацией кастомного groupBy. Задача
Дан массив объектов:
const users = [
{ name: 'Алиса', age: 21 },
{ name: 'Макс', age: 25 },
{ name: 'Ваня', age: 21 },
];
Нужно сгруппировать по возрасту:
groupBy(users, user => user.age);
// Результат:
// {
// 21: [{ name: 'Алиса', age: 21 }, { name: 'Ваня', age: 21 }],
// 25: [{ name: 'Макс', age: 25 }]
// }
Решение через
reduce:
function groupBy(array, fn) {
return array.reduce((acc, item) => {
const key = fn(item);
(acc[key] ||= []).push(item);
return acc;
}, {});
}
Как работает?
1.
reduce накапливает объект acc.2. Для каждого item вычисляем ключ через
fn(item).3. Если ключа нет в
acc, создаём массив.4. Добавляем
item в этот массив.5. Возвращаем обновлённый
acc.#JavaScript #interview
🔥9👍4
Привет! Сегодня разберём 🖼️ Он помогает находить потенциальные ошибки и улучшать качество кода.
Что делает StrictMode?
- Дважды вызывает функции (например,
- Подскажет, если вы используете методы, которые скоро удалят.
- Находит потенциальные баги, такие как мутации состояния или неправильная работа с хуками.
Как подключить?
Оберните приложение:
Советы
- Двойной рендер может раздражать, но он спасает от багов.
- Убедитесь, что
- Если добавляете
- Не отключайте
#react #BestPractices
StrictMode для разработки в React Что делает StrictMode?
StrictMode активирует дополнительные проверки в режиме разработки:- Дважды вызывает функции (например,
useEffect, useState, конструкторы классов), чтобы выявить побочные эффекты.- Подскажет, если вы используете методы, которые скоро удалят.
- Находит потенциальные баги, такие как мутации состояния или неправильная работа с хуками.
Как подключить?
Оберните приложение:
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Советы
- Двойной рендер может раздражать, но он спасает от багов.
- Убедитесь, что
useEffect и другие хуки идемпотентны (не ломаются при повторных вызовах).- Если добавляете
StrictMode в легаси проект, будьте готовы к сюрпризам.- Не отключайте
StrictMode без веской причины.#react #BestPractices
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍3
Привет 👋
Разберём полезный и редко используемый атрибут inputmode. Он говорит браузеру, какую клавиатуру показывать на мобильных устройствах при вводе данных.
Пример:
Пользователь увидит цифровую клавиатуру, хотя поле обычное текстовое.
Доступные значения inputmode
1.
2.
3.
4.
5.
6.
7.
8.
Когда использовать
- Для полей, где нужно показать пользователю подходящую клавиатуру для ввода
- Особенно полезно для номеров, кодов, адресов и поиска
Разница между type и inputmode
#HTML #BestPractices
Разберём полезный и редко используемый атрибут inputmode. Он говорит браузеру, какую клавиатуру показывать на мобильных устройствах при вводе данных.
Пример:
<input type="text" inputmode="numeric" placeholder="Введите номер телефона" />
Пользователь увидит цифровую клавиатуру, хотя поле обычное текстовое.
Доступные значения inputmode
1.
text — обычная клавиатура2.
none — клавиатура не показывается3.
tel — клавиатура с цифрами и символами телефона4.
numeric — только цифры5.
decimal — цифры и точка6.
email — клавиатура с @ и .7.
url — клавиатура с / и .8.
search — клавиатура для поиска с кнопкой “Поиск”Когда использовать
- Для полей, где нужно показать пользователю подходящую клавиатуру для ввода
- Особенно полезно для номеров, кодов, адресов и поиска
Разница между type и inputmode
inputmode отвечает только за то, какую клавиатуру показать пользователю, а type определяет, какие данные реально можно ввести.#HTML #BestPractices
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15👍7❤1
Привет! 👋
Хочу поделиться историей, которая началась этим летом в июле и до сих пор продолжается.
В одном из дворов мы заметили кота, который выглядел настолько плохо, что пройти мимо было просто невозможно. Худой, в ранах, с кучей проблем, о которых тогда мы ещё даже не подозревали.
Мы решили поймать его и отвезти в больницу, но это оказалось не так просто. Нам не удалось поймать его самим и пришлось искать человека, который умеет ловить животных. К счастью, нам удалось поймать его и отправить в больницу🏥
Дальше началась самая долгая и тяжёлая часть. Кот провёл много времени в больнице, а каждый день был похож на эмоциональные качели. Постоянно всплывали новые проблемы, долгое время не было никаких улучшений, и оставалось только ждать и надеяться. Я закидывал все анализы и слова врачей в ChatGPT чтобы получить еще одно мнение по состоянию. У кота было столько серьёзных заболеваний, что сложно представить, как он жил с ними. Врачи сделали невозможное🤯
Сейчас кот здоров настолько, насколько это вообще возможно для его возраста и того, что ему пришлось пережить. Он хорошо ест, набрал вес, живёт спокойной и размеренной жизнью. Он всё ещё боится, когда пытаешься его погладить, но его сердечко очень быстро тает❤️ У него остались некоторые особенности по здоровью, но это не мешает ему жить и не влияет на качество жизни. Просто котик со своими особенностями)
Кот с первого дня в больнице пользовался лотком и дома он тоже сразу показал себя как полностью домашний кот.
Из-за этого иногда появляется мысль что у него раньше уже был дом. Может он когда-то сбежал и потерялся, а может его просто выкинули.
Это был тяжёлый путь, но теперь у кота новая жизнь. Я очень надеюсь, что она будет долгой и без проблем со здоровьем.
К сожалению невозможно спасти всех животных, как бы этого ни хотелось. Я регулярно кормлю уличных котов, и каждый из них по-своему особенный. Кто-то боится и ждёт, а кто-то наоборот подбегает и хочет ласки. Каждый раз хочется потискать их всех, но не могу из-за своих домашних животных. Поэтому просто кормлю их и надеюсь, что у них тоже всё будет хорошо.
Любите котиков❤️
Хочу поделиться историей, которая началась этим летом в июле и до сих пор продолжается.
В одном из дворов мы заметили кота, который выглядел настолько плохо, что пройти мимо было просто невозможно. Худой, в ранах, с кучей проблем, о которых тогда мы ещё даже не подозревали.
Мы решили поймать его и отвезти в больницу, но это оказалось не так просто. Нам не удалось поймать его самим и пришлось искать человека, который умеет ловить животных. К счастью, нам удалось поймать его и отправить в больницу
Дальше началась самая долгая и тяжёлая часть. Кот провёл много времени в больнице, а каждый день был похож на эмоциональные качели. Постоянно всплывали новые проблемы, долгое время не было никаких улучшений, и оставалось только ждать и надеяться. Я закидывал все анализы и слова врачей в ChatGPT чтобы получить еще одно мнение по состоянию. У кота было столько серьёзных заболеваний, что сложно представить, как он жил с ними. Врачи сделали невозможное
Сейчас кот здоров настолько, насколько это вообще возможно для его возраста и того, что ему пришлось пережить. Он хорошо ест, набрал вес, живёт спокойной и размеренной жизнью. Он всё ещё боится, когда пытаешься его погладить, но его сердечко очень быстро тает
Кот с первого дня в больнице пользовался лотком и дома он тоже сразу показал себя как полностью домашний кот.
Из-за этого иногда появляется мысль что у него раньше уже был дом. Может он когда-то сбежал и потерялся, а может его просто выкинули.
Это был тяжёлый путь, но теперь у кота новая жизнь. Я очень надеюсь, что она будет долгой и без проблем со здоровьем.
К сожалению невозможно спасти всех животных, как бы этого ни хотелось. Я регулярно кормлю уличных котов, и каждый из них по-своему особенный. Кто-то боится и ждёт, а кто-то наоборот подбегает и хочет ласки. Каждый раз хочется потискать их всех, но не могу из-за своих домашних животных. Поэтому просто кормлю их и надеюсь, что у них тоже всё будет хорошо.
Любите котиков
Please open Telegram to view this post
VIEW IN TELEGRAM
❤26🔥6👏4
Уязвимость в React ⚠️
Команда разработки React сообщила об обнаружении критической уязвимости в серверных компонентах React, позволяющей выполнять удалённое выполнение кода на уязвимых серверах, использующих React Server Components.
Что случилось?
Ошибка в механизме обработки данных в RSC даёт возможность злоумышленнику отправить специально сформированный запрос и выполнить произвольный код на сервере без авторизации.
Уязвимость получила идентификатор CVE-2025-5518 и максимальный рейтинг критичности.
Кто в зоне риска?
Затронуты проекты, использующие пакеты react-server-dom-* версий 19.0-19.2.0, в том числе через такие фреймворки, как Next.js, React Router RSC, Vite RSC плагины и другие решения с поддержкой Server Components.
Что делать?⚠️
React уже выпустил исправления. Достаточно обновить зависимости до 19.0.1, 19.1.2 или 19.2.1. И убедитесь, что используемые фреймворки тоже подтянули фикс.
#react #security
Команда разработки React сообщила об обнаружении критической уязвимости в серверных компонентах React, позволяющей выполнять удалённое выполнение кода на уязвимых серверах, использующих React Server Components.
Что случилось?
Ошибка в механизме обработки данных в RSC даёт возможность злоумышленнику отправить специально сформированный запрос и выполнить произвольный код на сервере без авторизации.
Уязвимость получила идентификатор CVE-2025-5518 и максимальный рейтинг критичности.
Кто в зоне риска?
Затронуты проекты, использующие пакеты react-server-dom-* версий 19.0-19.2.0, в том числе через такие фреймворки, как Next.js, React Router RSC, Vite RSC плагины и другие решения с поддержкой Server Components.
Что делать?
React уже выпустил исправления. Достаточно обновить зависимости до 19.0.1, 19.1.2 или 19.2.1. И убедитесь, что используемые фреймворки тоже подтянули фикс.
#react #security
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3