ch
Feedback
Frontend | Вопросы собесов

Frontend | Вопросы собесов

前往频道在 Telegram

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv

显示更多

📈 Telegram 频道 Frontend | Вопросы собесов 的分析概览

频道 Frontend | Вопросы собесов (@easy_javascript_ru) 俄语 语言赛道中的 是活跃参与者。目前社区聚集了 17 873 名订阅者,在 技术与应用 类别中位列第 7 135,并在 俄罗斯 地区排名第 36 813

📊 受众指标与增长动态

невідомо 创建以来,项目保持高速增长,吸引了 17 873 名订阅者。

根据 27 八月, 2026 的最新数据,频道保持稳定运转。过去 30 天订阅人数变化为 -162,过去 24 小时变化为 -8,整体触达仍然可观。

  • 认证状态: 未认证
  • 互动率 (ER): 平均受众互动率为 6.80%。内容发布后 24 小时内通常能获得 4.51% 的反应,占订阅者总量。
  • 帖子覆盖: 每篇帖子平均可获得 1 216 次浏览,首日通常累积 806 次浏览。
  • 互动与反馈: 受众积极参与,单帖平均反应数为 4
  • 主题关注点: 内容集中在 ставь, браузер, html, border, flex 等核心主题上。

📝 描述与内容策略

作者将该频道定位为表达主观观点的平台:
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv

凭借高频更新(最新数据采集于 28 八月, 2026),频道始终保持新鲜度与高覆盖。分析显示受众积极互动,使其成为 技术与应用 类别中的关键影响点。

17 873
订阅者
-824 小时
-437
-16230
帖子存档
🤔 Как достигается изоляция при использовании бэм? БЭМ (Блок, Элемент, Модификатор) достигает изоляции стилей с помощью уникальных имен классов. Это помогает избежать конфликтов между стилями и делает код более предсказуемым. 🚩Как БЭМ предотвращает конфликты? 🟠Все стили зависят только от конкретного блока В БЭМ нет зависимостей от родительских элементов, поэтому стили блока не сломаются, если он окажется в другом месте.
<div class="button">Кнопка</div>
.button {
  background: blue;
  color: white;
}
Плохой пример без БЭМ
.container .button {
  background: blue;
}
🟠Элементы (`__`) зависят только от своего блока Стили элемента никогда не зависят от родителя — только от блока.
<div class="card">
  <h2 class="card__title">Заголовок</h2>
  <p class="card__text">Текст карточки</p>
</div>
.card__title {
  font-size: 20px;
}

.card__text {
  color: gray;
}
🟠Модификаторы (`--`) изменяют только нужные стили Модификаторы позволяют изменять внешний вид без переписывания базовых стилей.
<button class="button button--red">Кнопка</button>
<button class="button button--blue">Кнопка</button>
.button {
  padding: 10px;
  border-radius: 5px;
}

.button--red {
  background: red;
}

.button--blue {
  background: blue;
}
🟠Имена классов уникальны, нет глобальных стилей В БЭМ не используется tag {} или id {} — только классы. Это предотвращает конфликты стилей.
h1 {
  color: red;
}
БЭМ-версия
.card__title {
  color: red;
}
Ставь 👍 и забирай 📚 Базу знаний

Битва кейсов ИБ: 6 сценариев киберкошмара 7 апреля в поединке сойдутся эксперты «Солара». По одну сторону — кейсы тестировани
Битва кейсов ИБ: 6 сценариев киберкошмара 7 апреля в поединке сойдутся эксперты «Солара». По одну сторону — кейсы тестирований на проникновение, по другую — реальные атаки. Чьи сценарии окажутся страшнее и критичнее — покажет битва. Кому будет полезно: Руководителям ИБ и ИБ-специалистам — получить данные, чтобы обосновать бюджет и построить стратегию защиты. ИТ-руководителям и менеджерам — узнать о текущих рисках и понять, как спланировать ИБ-бюджет. Руководителям компаний и риск-менеджерам — снизить цифровые и финансовые риски, защитить репутацию. Приходите, чтобы на чужих ошибках закрыть пробелы в своей защите. Зарегистрироваться #реклама 16+ rt-solar.ru О рекламодателе

🤔 Как принудительно обновить компонент во Vue? Иногда Vue может не понять, что данные изменились. В таком случае можно заставить компонент перерисоваться. Один способ — изменить значение key у компонента, это заставит его перерисоваться заново. Также можно использовать локальное реактивное состояние, которое сбрасывается и снова включает компонент. В крайнем случае используют forceUpdate, но это плохая практика. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Зачем нужен eslint? ESLint – это инструмент для автоматического анализа и исправления кода в JavaScript и TypeScript. Он помогает разработчикам следовать единым стилям кодирования, находить ошибки и предотвращать баги ещё до запуска кода. 🚩Почему ESLint полезен? Без линтера код может быть неаккуратным и содержать ошибки, которые сложно отловить. 🚩Проблемы без ESLint Разные стили написания кода Пропущенные точки с запятой или лишние пробелы Неиспользуемые переменные Ошибки, которые не выявляются во время компиляции (например, undefined переменные) 🚩Решение с ESLint: Автоматически находит ошибки и предупреждения Подсказывает лучшие практики Поддерживает кастомные правила Работает в IDE и CI/CD (автоматическая проверка) 🟠Как ESLint работает? ESLint использует набор правил, которые проверяют код. Если код нарушает эти правила – линтер выдаёт предупреждение или ошибку.
function sayHello(name) {
  console.log("Hello, " + name)
}

sayHello("John")
Пример исправленного кода (ESLint fix)
function sayHello(name) {
  console.log(`Hello, ${name}`);
}

sayHello("John");
🟠Как установить и настроить ESLint? Установка
npm install eslint --save-dev
Создание конфига
npx eslint --init
Пример .eslintrc.js (настройки ESLint)
module.exports = {
  env: {
    browser: true,
    es6: true,
  },
  extends: [
    "eslint:recommended", // Базовые рекомендации
    "plugin:vue/vue3-recommended" // Рекомендации для Vue
  ],
  rules: {
    "no-unused-vars": "warn", // Предупреждать о неиспользуемых переменных
    "semi": ["error", "always"], // Обязательные точки с запятой
    "quotes": ["error", "double"], // Только двойные кавычки
  },
};
Запуск проверки кода
npx eslint myfile.js
Автоматическое исправление ошибок
npx eslint myfile.js --fix
🟠ESLint в IDE (VS Code, WebStorm) Чтобы ESLint работал в VS Code, установите расширение ESLint и включите "editor.codeActionsOnSave"
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
}
🟠ESLint в CI/CD (автоматическая проверка на сервере) В проектах ESLint можно запускать в GitHub Actions, Jenkins, GitLab CI и других CI/CD системах, чтобы не допускать ошибок в main ветку.
"scripts": {
  "lint": "eslint src --fix"
}
Теперь перед коммитом можно запускать:
npm run lint
Ставь 👍 и забирай 📚 Базу знаний

🤔 Какие есть способы модификации цвета? Можно изменить прозрачность, использовать фильтры, градиенты, наложения и тени. Также можно программно управлять цветом, меняя его тон, насыщенность, яркость через функции препроцессоров или CSS-функции. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Зачем нам разбивать приложение отдельно на backend и frontend? Разделение на Frontend (клиент) и Backend (сервер) – это стандартный подход в современной веб-разработке. Это делает приложение гибче, масштабируемее и удобнее в разработке. 🚩Почему лучше разделять? 🟠Гибкость и масштабируемость Можно менять Frontend и Backend независимо. Можно использовать разные технологии (например, Vue.js + Django). Можно легко разделить команды разработчиков. 🟠Повышенная безопасность Frontend не имеет доступа к базе данных. Все важные вычисления, авторизация, хранение данных происходят на сервере. API можно защитить токенами (JWT, OAuth). 🟠Уменьшение нагрузки на клиент Логика обработки данных выполняется на сервере. Клиент получает уже готовые данные, а не загружает огромные файлы. 🟠Легче разрабатывать и тестировать Можно разрабатывать Frontend и Backend независимо. Можно подменять сервер на mock-данные во время разработки. 🚩Как они общаются? (REST API & GraphQL) Разделённые приложения общаются через API: REST API (GET, POST, PUT, DELETE) GraphQL API (запросы только нужных данных) WebSockets (реальное время, чаты, онлайн-игры)
GET https://api.example.com/users
Ответ от Backend
[
  { "id": 1, "name": "Alice" },
  { "id": 2, "name": "Bob" }
]
Ставь 👍 и забирай 📚 Базу знаний

Нейросеть проверит 100% закупок на стройке за минуты! 👍Контроль закупок за 15 минут в день. Нейросеть "Тринити" экономит ваш
Нейросеть проверит 100% закупок на стройке за минуты! 👍Контроль закупок за 15 минут в день. Нейросеть "Тринити" экономит ваше время и миллионы рублей Вы - генеральный директор строительной компании, и у вас катастрофически не хватает времени? Работаете 12+ часов в день и не можете контролировать каждую закупку? 💰Тратите миллионы на закупки, но не уверены, что получаете лучшие цены и качество? Хотите спать спокойно, зная, что ваши деньги под защитой? Просто загрузите счет или тендерный протокол в Telegram-бот Получите детальный анализ по 18 параметрам за 1 минуту Экономьте до 10% на каждой закупке без дополнительных усилий В 3-5 раз дешевле, чем содержать штат контролеров! Работает 24/7 без выходных и отпусков. 👌Узнайте про наш телеграм-бот и тестируйте бесплатно 7 дней! Экономия в первый же день. Перейти на сайт #реклама 16+ trinitysafe.ru О рекламодателе

🤔 Как заредиректить пользователя на URL? Можно изменить свойство, отвечающее за текущий адрес страницы, или вызвать метод, который вызывает загрузку другого URL. Это работает как обычный переход по ссылке. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Что такое шаблонные литералы, и для чего они нужны? Были введены в ECMAScript 2015 (ES6) и представляют собой улучшение стандартных строк в JavaScript. Они облегчают работу с строками, предоставляя более удобный синтаксис для создания многострочных строк, интерполяции переменных и встроенных выражений. 🚩Примеры использования 🟠Интерполяция переменных и выражений Шаблонные литералы позволяют встраивать переменные и выражения внутрь строк с помощью синтаксиса ${}.
const name = 'Alice';
const age = 25;

const greeting = `Hello, my name is ${name} and I am ${age} years old.`;

console.log(greeting);
// Вывод: Hello, my name is Alice and I am 25 years old.
🟠Многострочные строки Шаблонные литералы позволяют создавать многострочные строки без необходимости использования символов переноса строки (\n).
const multiLineString = `This is a string
that spans across
multiple lines.`;

console.log(multiLineString);
// Вывод:
// This is a string
// that spans across
// multiple lines.
🟠Встроенные выражения Внутри шаблонных литералов можно использовать любые JavaScript-выражения.
const a = 5;
const b = 10;

const result = `The sum of ${a} and ${b} is ${a + b}.`;

console.log(result);
// Вывод: The sum of 5 and 10 is 15.
🟠Вызов функций внутри шаблонных литералов Можно вызывать функции и методы внутри шаблонных литералов.
function toUpperCase(str) {
    return str.toUpperCase();
}

const name = 'Alice';

const loudGreeting = `Hello, ${toUpperCase(name)}!`;

console.log(loudGreeting);
// Вывод: Hello, ALICE!
🟠Тегированные шаблонные литералы Тегированные шаблонные литералы позволяют обработать строку с помощью функции перед ее окончательной интерпретацией.
function tag(strings, ...values) {
    console.log(strings);
    console.log(values);
    return 'Tagged template';
}

const name = 'Alice';
const age = 25;

const taggedResult = tag`Name: ${name}, Age: ${age}`;

console.log(taggedResult);
// Вывод:
// [ 'Name: ', ', Age: ', '' ]
// [ 'Alice', 25 ]
// Tagged template
Ставь 👍 и забирай 📚 Базу знаний

Увеличьте память телефона до бесконечности Безлимитное место для фото и видео с телефона в Облаке — 3 месяца за 0 ₽ Незаменим
Увеличьте память телефона до бесконечности Безлимитное место для фото и видео с телефона в Облаке — 3 месяца за 0 ₽ Незаменимо, когда память телефона переполнена, а нужно фотографировать прямо сейчас Узнать больше #реклама 16+ cloud.mail.ru О рекламодателе

🤔 Что такое псевдоэлемент? Псевдоэлемент — это CSS-конструкция, которая позволяет стилизовать определённые части элемента, например, ::before для добавления контента перед элементом или ::after для добавления после. Это удобно для оформления, не изменяя HTML-структуру. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Как считается вес селектора? Вес селектора (специфичность) – это правило, по которому браузер определяет, какой стиль применить, если есть несколько конфликтующих селекторов.
( inline, id, class/атрибут/псевдокласс, элемент/псевдоэлемент )
Пример
/* Специфичность: (0, 1, 0, 0) */
#header { color: red; }

/* Специфичность: (0, 0, 1, 0) */
.header { color: blue; }

/* Специфичность: (0, 0, 0, 1) */
h1 { color: green; }
🟠Примеры сравнения специфичности Пример 1
h1 { color: red; } /* (0,0,0,1) */
.title { color: blue; } /* (0,0,1,0) */
Пример 2
h1 { color: red; } /* (0,0,0,1) */
#main { color: blue; } /* (0,1,0,0) */
Пример 3 (комбинированные селекторы)
h1.title { color: red; } /* (0,0,1,1) */
#main h1 { color: blue; } /* (0,1,0,1) */
Пример 4 (инлайн-стиль всегда сильнее)
<h1 style="color: green;">Заголовок</h1>
h1 { color: red; } /* (0,0,0,1) */
.title { color: blue; } /* (0,0,1,0) */
#main { color: purple; } /* (0,1,0,0) */
🟠Как повысить вес селектора? Добавить ID (но не злоупотреблять). Использовать более специфичные селекторы (например, .header h1 вместо h1). Использовать !important (но осторожно!).
h1 { color: red !important; } /* Всегда будет красным */
Ставь 👍 и забирай 📚 Базу знаний

Бесплатная конференция по PostgreSQL — уже 19 марта! Регистрируйся на бесплатную конференцию по PostgreSQL — 19.03.2026. В фо
Бесплатная конференция по PostgreSQL — уже 19 марта! Регистрируйся на бесплатную конференцию по PostgreSQL — 19.03.2026. В фокусе — практический опыт эксплуатации PostgreSQL, ее внутреннее устройство, производительность, взаимодействие с другими системами и реальные кейсы из highload-среды. Мероприятие в формате онлайн+офлайн, 25+ тематических докладов, 3 потока. Вот некоторые темы конференции: ✅ Опыт выноса OLAP-нагрузки на реплику ✅ Временные таблицы в PostgreSQL: почему это критично для платформы 1С и что можно улучшить ✅ Разделение Compute и Storage: архитектурный прорыв для PostgreSQL в облаке ✅ Highload «из ниоткуда»: когда узкое место — не в СУБД, а в клиентской архитектуре ✅ Работа с логами PostgreSQL Регистрируйся, будет интересно! И бесплатно! Зарегистрироваться #реклама 16+ pgbootcamp.ru О рекламодателе

🤔 Какие способы сортировки массива есть? В JavaScript массивы сортируются с помощью метода sort() Также можно использовать: - Сортировку по строкам (по умолчанию): arr.sort() - Сортировку по свойствам объектов: - users.sort((a, b) => a.age - b.age); - Создание новых отсортированных массивов без мутации: - const sorted = [...arr].sort(); Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Что такое merge и rebase, в чем отличие друг от друга? Это два способа интеграции изменений из одной ветки в другую в системе контроля версий Git. Оба метода имеют свои особенности и подходят для разных сценариев. 🚩Merge (слияние) Объединяет изменения из одной ветки в другую, создавая новый коммит слияния (merge commit). Этот метод сохраняет историю всех коммитов, включая все ветвления и слияния. Предположим, у вас есть две ветки: main и feature. В ветке feature вы сделали несколько коммитов. Вы хотите объединить изменения из feature в main.
git checkout main
git merge feature
🚩Rebase (перебазирование) Перемещает или переписывает базу текущей ветки на указанную базу другой ветки. Это переписывает историю коммитов, создавая новые коммиты для каждого из оригинальных коммитов. Предположим, у вас есть две ветки: main и feature. В ветке feature вы сделали несколько коммитов. Вы хотите перенести изменения из feature на текущий конец main.
git checkout feature
git rebase main
🚩Основные отличия 🟠История коммитов Merge: Сохраняет всю историю, включая коммиты слияния. История показывает, когда и как происходили слияния веток. Rebase: Переписывает историю, делая её линейной. История показывает, как если бы все изменения были сделаны последовательно, без ветвлений. 🟠Коммиты слияния Merge: Создает новый коммит слияния, который объединяет изменения из двух веток. Rebase: Не создает коммит слияния. Перебазирование "переносит" коммиты одной ветки на другую. 🟠Конфликты Merge: Конфликты решаются один раз при слиянии. Rebase: Конфликты могут возникнуть на каждом коммите, и их нужно решать поэтапно. 🟠Применение Merge: Хорош для сохранения полного контекста истории разработки, особенно в командной работе. Rebase: Хорош для поддержания чистой, линейной истории, особенно перед слиянием ветки в основную ветку, например, main или master. Ставь 👍 и забирай 📚 Базу знаний

🤔 Как работает поток данных между Redux и компонентом? Компонент получает данные из Redux через функции useSelector или connect(). При изменении состояния Redux происходит перерисовка. Чтобы изменить состояние, компонент диспатчит action через dispatch. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Почему map используют чаще, чем объект? Хотя объекты {} исторически использовались как ассоциативные массивы (ключ-значение), у Map есть ряд преимуществ, которые делают его более удобным в большинстве случаев. 🟠`Map` может использовать любые типы данных в качестве ключей В объектах {} ключи всегда автоматически приводятся к строке.
const obj = {};
const key1 = {};
const key2 = {};

obj[key1] = "value1";
obj[key2] = "value2";

console.log(obj); // { '[object Object]': 'value2' }
console.log(obj[key1]); // "value2" (ключи перезаписались, потому что оба стали "[object Object]")
Пример с Map:
const map = new Map();
map.set(key1, "value1");
map.set(key2, "value2");

console.log(map.get(key1)); // "value1"
console.log(map.get(key2)); // "value2"
🟠`Map` хранит порядок ключей В объекте {} порядок ключей не гарантируется (особенно для числовых ключей).
const obj = { 2: "two", 1: "one", 3: "three" };
console.log(Object.keys(obj)); // ["1", "2", "3"] (порядок числовых ключей изменился!)
Пример с Map
const map = new Map();
map.set(2, "two");
map.set(1, "one");
map.set(3, "three");

console.log([...map.keys()]); // [2, 1, 3] (порядок сохраняется!)
🟠`Map` быстрее при частых добавлениях/удалениях Объекты {} оптимизированы для хранения структуры данных, но операции delete и Object.keys(obj).length могут быть медленными, потому что движок JavaScript выполняет дополнительные проверки. Разница в скорости В Map операции .set(), .get(), .delete() выполняются быстрее. В объекте {} delete obj[key] может работать медленнее, так как JavaScript оптимизирует объекты для других целей. 🟠У `Map` есть удобные методы Объект {} не имеет встроенных методов для работы с ключами и значениями. Чтобы, например, узнать размер объекта, приходится использовать Object.keys(obj).length.
const map = new Map();
map.set("a", 1);
map.set("b", 2);

console.log(map.size); // 2
console.log(map.has("a")); // true
console.log(map.delete("b")); // true (удалит "b")
В объекте {}
const obj = { a: 1, b: 2 };

console.log(Object.keys(obj).length); // 2 (нужно вызывать Object.keys())
console.log(obj.hasOwnProperty("a")); // true (менее удобный синтаксис)
delete obj.b; // Удаление ключа
🟠`Map` не имеет проблем с прототипами В объекте {} могут быть неожиданные проблемы, если ключ совпадает с именем встроенного метода.
const obj = {};
console.log(obj.toString); // [Function: toString] (унаследованное свойство!)
console.log(obj["toString"]); // [Function: toString] (может вызвать баги)
Чтобы обойти это, приходится делать так
const obj = Object.create(null); // Теперь у объекта нет прототипа
obj.toString = "custom";
console.log(obj.toString); // "custom"
В Map таких проблем нет
const map = new Map();
map.set("toString", "custom");
console.log(map.get("toString")); // "custom" (никаких багов!)
Ставь 👍 и забирай 📚 Базу знаний

Бесплатный курс: веб-дизайн, графика, интерфейсы Научись создавать дизайн сайтов и приложений, инфографику для карточек на ма
Бесплатный курс: веб-дизайн, графика, интерфейсы Научись создавать дизайн сайтов и приложений, инфографику для карточек на маркетплейсах и работать в Figma! Студенты курса в среднем зарабатывают от 68 000 ₽ уже во время обучения💰 Этот курс для тебя, если ты: ✅ мечтаешь о новой профессии, но не знаешь, с чего начать; ✅ чувствуешь, что хочешь большего — свободы, самореализации, творчества; ✅ полный новичок и хочешь систему, а не хаос; ✅ хочешь начать зарабатывать удалённо. Зарегистрироваться #реклама 16+ ydaev.ru О рекламодателе

🤔 Как передать данные из родительского компонента в дочерний? Данные передаются с использованием props. 1. Родительский компонент передаёт данные через атрибуты в дочерний компонент. 2. Дочерний компонент принимает их, определяя props в своей конфигурации. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚 Базу знаний

🤔 Как определить что состояние является глобальным? Глобальное состояние – это данные, которые должны быть доступны в разных частях приложения. Чтобы определить, является ли состояние глобальным, нужно задать себе несколько вопросов: 🚩Используется ли это состояние в нескольких независимых компонентах? Если одно и то же состояние необходимо сразу нескольким компонентам, расположенным в разных частях дерева компонентов, скорее всего, его стоит сделать глобальным. В React, если в разных компонентах нужна информация о текущем пользователе (user), лучше хранить её в глобальном состоянии (например, в Context или Redux).
// Глобальное состояние (например, Context API)
const UserContext = createContext();

function App() {
  const [user, setUser] = useState({ name: "Иван", isLoggedIn: true });

  return (
    <UserContext.Provider value={user}>
      <Navbar />
      <Profile />
    </UserContext.Provider>
  );
}

function Navbar() {
  const user = useContext(UserContext);
  return <div>Привет, {user.name}!</div>;
}

function Profile() {
  const user = useContext(UserContext);
  return <div>Профиль пользователя: {user.name}</div>;
}
🚩Должно ли состояние сохраняться при переходе между страницами? Если данные должны оставаться неизменными при смене страниц, лучше использовать глобальное хранилище (например, Redux, Zustand или React Context). Корзина товаров в интернет-магазине Авторизация пользователя Темная/светлая тема приложения Если данные теряются при смене страницы – это сигнал, что их нужно вынести в глобальное хранилище. 🚩Может ли состояние изменяться в одном месте, а использоваться в другом? Если одно состояние обновляется в одном компоненте, но влияет на работу нескольких других компонентов, оно должно быть глобальным. В чате, если новое сообщение приходит в одном компоненте (ChatInput), а отображается в другом (ChatList), логично хранить все сообщения в глобальном состоянии.
const ChatContext = createContext();

function ChatProvider({ children }) {
  const [messages, setMessages] = useState([]);

  const sendMessage = (text) => {
    setMessages([...messages, { text, id: Date.now() }]);
  };

  return (
    <ChatContext.Provider value={{ messages, sendMessage }}>
      {children}
    </ChatContext.Provider>
  );
}

function ChatList() {
  const { messages } = useContext(ChatContext);
  return messages.map((msg) => <p key={msg.id}>{msg.text}</p>);
}

function ChatInput() {
  const { sendMessage } = useContext(ChatContext);
  const [text, setText] = useState("");

  return (
    <input
      value={text}
      onChange={(e) => setText(e.target.value)}
      onKeyPress={(e) => {
        if (e.key === "Enter") {
          sendMessage(text);
          setText("");
        }
      }}
    />
  );
}
🚩Зависит ли состояние от URL (адресной строки)? Иногда состояние можно не делать глобальным, а просто хранить его в URL (в query-параметрах или path). ID открытого товара: /products/123 Фильтры товаров: /shop?category=shoes&sort=price Страница чата с пользователем: /chat?user=ivan Ставь 👍 и забирай 📚 Базу знаний