Vue SFC (однофайловые компоненты) — как аквариум: HTML, JS, CSS плавают рядышком, но не мешают друг другу.
JSX — это когда рыбы, водоросли и фильтры свалены в одну кучу, зато можно собрать подводный велосипед.
Vue SFC (однофайловые компоненты) — как аквариум: HTML, JS, CSS плавают рядышком, но не мешают друг другу.
JSX — это когда рыбы, водоросли и фильтры свалены в одну кучу, зато можно собрать подводный велосипед.
После прочтения темы вспомнился мой любимый способ борьбы с вечным undefined — создание «защитного пояса» вокруг данных. Вот что спасает меня в Next.js и React:
TypeScript + Strict Null Checks:
Включите strict: true в tsconfig.json — это как поставить железную дверь между вами и undefined. Теперь тип any придётся явно кастить, а неинициализированные состояния будут кричать на этапе компиляции.
Спасательный крюк для SSR:
В Next.js данные с сервера иногда приходят «неожиданно пустыми». Делаю так:
const SafeComponent = ({ data }: { data: unknown }) => {
const [isHydrated, setIsHydrated] = useState(false);
useEffect(() => setIsHydrated(true), []);
if (!isHydrated || !data) return <Skeleton />; // Или котик-лоадер 🐈⬛
// ...рендер
};
Это помогает избежать конфликтов гидратации и внезапных Cannot read property 'map' of undefined.
Магия Proxy для дебага:
Подменяю объекты в режиме разработки прокси, который логирует все попытки доступа к undefined:
const createSafeObject = (obj) => {
if (process.env.NODE_ENV === "development") {
return new Proxy(obj, {
get(target, prop) {
if (target[prop] === undefined) {
console.trace(`Пойман undefined в свойстве ${prop.toString()}`);
}
return target[prop];
},
});
}
return obj;
};
А ещё держу на рабочем столе фото Шредингера — напоминание, что состояние переменной может быть и undefined, и не undefined, пока ты не заглянешь в консоль.
Vue — как мультиварка, React — как конструктор для молекулярной кухни
Vue с его HTML-шаблонами и директивой v-model напоминает готовый рецепт: положил ингредиенты, закрыл крышку — блюдо готово. Особенно с script setup в Composition API
React же — это когда вы собираете стейк из атомов, а потом удивляетесь, почему он пахнет квантовой физикой. Хуки, кастомные провайдеры, useMemo… Зато можно создать блюдо, которого никто раньше не видел (или не хотел видеть ).
Тема замены классического class-validator
на Zod в NestJS зацепила — сам недавно экспериментировал с этим связкой. Делюсь мыслями и болью:
class CreateUserDto {
@IsString()
@Length(3, 20)
name: string;
}
const CreateUserSchema = z.object({
name: z.string().min(3).max(20).transform(val => val.trim()),
});
type CreateUserDto = z.infer<typeof CreateUserSchema>;
Никаких двойных объявлений — схема диктует тип.
Заменить стандартный pipe на Zod-версию можно так:
import { PipeTransform, Injectable } from '@nestjs/common';
import { ZodSchema } from 'zod';
@Injectable()
export class ZodValidationPipe implements PipeTransform {
constructor(private schema: ZodSchema) {}
transform(value: unknown) {
return this.schema.parse(value); // Выбросит исключение при ошибке
}
}
// В контроллере:
@Post()
@UsePipes(new ZodValidationPipe(CreateUserSchema))
createUser(@Body() dto: CreateUserDto) { /* ... */ }
Или использовать готовые обёртки вроде nestjs-zod
, если лень писать велосипеды.
Zod позволяет кастомизировать сообщения глобально или для конкретного поля:
const schema = z.object({
email: z.string().email("Почта выглядит подозрительно 👀"),
});
А потом ловить их в ExceptionFilter NestJS и возвращать клиенту в человекочитаемом виде.
class-validator
требует кастомных декораторов.class-validator
— возможно, не стоит ломать.