Привет) Начнем неделю с разобора as const в 🖼️
Что такое as const?
Это утверждение константности в TypeScript, которое делает объект, массив или примитив иммутабельным на уровне типов. Оно говорит компилятору, что значение не будет меняться, а его свойства или элементы становятся литеральными типами. С
Рассмотрим объект с настройками:
Здесь TypeScript считает, что
Добавим as const:
Теперь
Тоже самое будет с массивами и другими.
Какие плюсы это даёт?
— Вы работаете с конкретными значениями, а не с общими типами (
—
— Редактор кода лучше подсказывает значения, так как знает точные литералы.
— Меньше багов из-за неожиданных значений.
Итого:
Используйте
#typescript
Что такое as const?
Это утверждение константности в TypeScript, которое делает объект, массив или примитив иммутабельным на уровне типов. Оно говорит компилятору, что значение не будет меняться, а его свойства или элементы становятся литеральными типами. С
as const фиксируются точные значения.Рассмотрим объект с настройками:
const config = {
mode: "development",
port: 3000,
};
// TypeScript выводит тип: { mode: string; port: number }
config.mode = "production"; // Без проблем
Здесь TypeScript считает, что
mode — это просто string.Добавим as const:
const config = {
mode: "development",
port: 3000,
} as const;
// Тип теперь: { readonly mode: "development"; readonly port: 3000 }
config.mode = "production"; // Ошибка: Cannot assign to 'mode' because it is a read-only property
Теперь
config имеет точный тип, где mode — это буквально "development", а port — буквально 3000. Плюс, свойства стали readonly, что защищает их от изменений.Тоже самое будет с массивами и другими.
Какие плюсы это даёт?
— Вы работаете с конкретными значениями, а не с общими типами (
string, number и т.д.).—
as const предотвращает случайные изменения объектов или массивов.— Редактор кода лучше подсказывает значения, так как знает точные литералы.
— Меньше багов из-за неожиданных значений.
Итого:
Используйте
as const, когда хотите зафиксировать точные значения объектов, массивов или примитивов, особенно в конфигурациях, словарях или наборах констант, но не злоупотребляйте)#typescript
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍5👨💻1
Бывают ситуации, когда нужно развернуть вложенный массив. Некоторые начинают писать
Что делает?
Метод
Примеры
По умолчанию разворачивает массив на 1 уровень вложенности. Но можно указать нужную глубину или даже развернуть массив полностью.
Если массив имеет несколько уровней вложенности, можно указать, на сколько уровней его развернуть:
Здесь
Если неизвестно количество уровней вложенности в массиве, то подойдет
Основные моменты
1. f
2. Без аргумента разворачивает только на один уровень.
#JavaScript
reduce и вручную перебирать вложенность. В JS есть готовое решение — метод flat().Что делает?
Метод
flat() разворачивает вложенные массивы на указанную глубину, создавая новый массив.Примеры
const arr = [1, [2, 3], [4, [5]]];
console.log(arr.flat()); // [1, 2, 3, 4, [5]]
По умолчанию разворачивает массив на 1 уровень вложенности. Но можно указать нужную глубину или даже развернуть массив полностью.
Если массив имеет несколько уровней вложенности, можно указать, на сколько уровней его развернуть:
const arr = [1, [2, 3], [4, [5, [6]]]];
console.log(arr.flat(2)); // [1, 2, 3, 4, 5, [6]]
Здесь
flat(2) развернул массив на два уровня.Если неизвестно количество уровней вложенности в массиве, то подойдет
Infinity:
const arr = [1, [2, [3, [4, [5]]]]];
console.log(arr.flat(Infinity)); // [1, 2, 3, 4, 5]
Основные моменты
1. f
lat() не изменяет исходный массив, а возвращает новый.2. Без аргумента разворачивает только на один уровень.
#JavaScript
🔥8👍4
Привет! Начнем неделю с разбора интересного метода
Метод
Синтаксис:
1.
2.
Как это работает?
Если длина исходной строки меньше
Примеры использования
1. Форматирование чисел с ведущими нулями
2. Форматирование даты
Основные моменты:
1. Если
2. Если
3.
Поддержка браузерами: canIUse
#JavaScript
padStart.Метод
padStart добавляет в начало строки указанные символы (пробелы по умолчанию), пока строка не достигнет заданной длины. Синтаксис:
string.padStart(targetLength, padString)
1.
targetLength: желаемая длина строки после дополнения.2.
padString: символы, которыми дополняется строка (по умолчанию — пробел).Как это работает?
Если длина исходной строки меньше
targetLength, метод добавляет padString в начало, пока строка не станет нужной длины. Если строка уже длиннее или равна targetLength, она остаётся без изменений.Примеры использования
1. Форматирование чисел с ведущими нулями
const num = '42';
console.log(num.padStart(5, '0')); // "00042"
2. Форматирование даты
const day = '7';
const month = '3';
console.log(day.padStart(2, '0')); // "07"
console.log(month.padStart(2, '0')); // "03"
// Получаем: "03.07"
Основные моменты:
1. Если
padString длиннее, чем нужно, он обрезается до необходимой длины.2. Если
targetLength меньше длины строки, метод возвращает строку без изменений.3.
padStart возвращает новую строку.Поддержка браузерами: canIUse
#JavaScript
🔥9👍4
Продолжаем разбирать SOLID. Сегодня буква I — Interface Segregation Principle (принцип разделения интерфейсов).
О чём этот принцип?
Клиенты не должны зависеть от методов, которые они не используют. Интерфейсы должны быть узкими и заточенными под конкретную задачу.
Если проще — интерфейсы и контракты классов должны быть узкими и содержать только те методы, которые действительно нужны конкретному клиенту.
Иначе классам придётся реализовывать ненужные методы или выбрасывать исключения.
Пример плохого подхода
Как улучшить?
Разделим интерфейсы на специфичные:
Теперь каждый класс реализует только то, что нужно.
Что это даёт?
— Код чище и проще для поддержки
— Меньше шансов вызвать неподдерживаемый метод
— Легче расширять систему
Дробите интерфейсы на небольшие части, чтобы классы не наследовали ненужные методы.
#BestPractices #JavaScript #typescript
О чём этот принцип?
Клиенты не должны зависеть от методов, которые они не используют. Интерфейсы должны быть узкими и заточенными под конкретную задачу.
Если проще — интерфейсы и контракты классов должны быть узкими и содержать только те методы, которые действительно нужны конкретному клиенту.
Иначе классам придётся реализовывать ненужные методы или выбрасывать исключения.
Пример плохого подхода
interface Device {
print(doc: string): void;
scan(doc: string): void;
fax(doc: string): void;
}
class SimplePrinter implements Device {
print(doc: string): void {
console.log(`Печатаю: ${doc}`);
}
scan(doc: string): void {
throw new Error('Не поддерживает сканирование');
}
fax(doc: string): void {
throw new Error('Не поддерживает факс');
}
}
SimplePrinter вынужден наследовать методы scan и fax, которые ему не нужны, что нарушает принцип.Как улучшить?
Разделим интерфейсы на специфичные:
interface Printable {
print(doc: string): void;
}
interface Scannable {
scan(doc: string): void;
}
interface Faxable {
fax(doc: string): void;
}
class SimplePrinter implements Printable {
print(doc: string): void {
console.log(`Печатаю: ${doc}`);
}
}
Теперь каждый класс реализует только то, что нужно.
Что это даёт?
— Код чище и проще для поддержки
— Меньше шансов вызвать неподдерживаемый метод
— Легче расширять систему
Дробите интерфейсы на небольшие части, чтобы классы не наследовали ненужные методы.
#BestPractices #JavaScript #typescript
❤9👍5
Привет! Обычно для группировки я использую
1.
2.
Пример данных с которыми будем дальше работать:
Object.groupBy:
Map.groupBy:
Разница
1.
2.
Встроенные методы — классная альтернатива без зависимостей, но Lodash остаётся для меня удобным и универсальным инструментом)
#JavaScript
groupBy из Lodash, но в самом JavaScript тоже есть встроенные методы: 1.
Object.groupBy 2.
Map.groupByПример данных с которыми будем дальше работать:
const users = [
{ name: "Аня", age: 25, city: "Москва" },
{ name: "Иван", age: 30, city: "Москва" },
{ name: "Оля", age: 22, city: "Казань" },
{ name: "Петя", age: 30, city: "Казань" },
];
Object.groupBy:
const byCity = Object.groupBy(users, user => user.city);
console.log(byCity);
// {
// "Москва": [ { name: "Аня", age: 25 }, { name: "Иван", age: 30 } ],
// "Казань": [ { name: "Оля", age: 22 }, { name: "Петя", age: 30 } ]
// }
Map.groupBy:
const byAge = Map.groupBy(users, user => user.age);
console.log(byAge);
// Map(3) {
// 25 => [ { name: "Аня", age: 25 } ],
// 30 => [ { name: "Иван", age: 30 }, { name: "Петя", age: 30 } ],
// 22 => [ { name: "Оля", age: 22 } ]
// }
Разница
1.
Object.groupBy - возвращает объект, ключи всегда строки.2.
Map.groupBy - возвращает Map, где ключи могут быть любыми.Встроенные методы — классная альтернатива без зависимостей, но Lodash остаётся для меня удобным и универсальным инструментом)
#JavaScript
👍9🔥7👏1
В проектах часто встречается рендер через логический оператор И:
Если
А что если мы хотим вывести компонент при одном из условий?
Можно написать так:
Но тут есть какой-то подвох... Он не всегда бросается в глаза.
Из-за приоритета операторов И(
Поэтому этот код на самом деле работает так:
В результате компонент появится только тогда, когда
Чтобы логика работала правильно, достаточно добавить группировку:
Теперь компонент отрендерится, если хотя бы одно условие истинно.
Но на самом деле можно упростить ещё больше. Я уже писал про условный рендер в этом посте(тык). Он выглядит понятнее и не заставляет задумываться о приоритетах:
Так код читается сразу и не заставляет думать лишний раз.
#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