MDX (Markdown + JSX) позволяет использовать JavaScript внутри Markdown, что открывает возможности динамического рендеринга компонентов. Одним из ключевых аспектов безопасной и корректной работы с MDX является проверка входных данных, особенно когда компоненты получают пропсы из внешних источников. Непроверенные данные могут привести к ошибкам рендеринга, некорректной работе логики компонентов или даже уязвимостям безопасности.
В MDX-компонентах часто применяются React-компоненты. Для проверки типов данных можно использовать библиотеку PropTypes:
import PropTypes from 'prop-types';
const UserCard = ({ name, age, email }) => (
<div>
<h2>{name}</h2>
<p>Возраст: {age}</p>
<p>Email: {email}</p>
</div>
);
UserCard.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
email: PropTypes.string,
};
Ключевые моменты:
isRequired гарантирует, что пропс не будет
undefined или null.MDX полностью поддерживает TypeScript, что позволяет использовать строгую типизацию для пропсов:
interface UserCardProps {
name: string;
age: number;
email?: string;
}
const UserCard: React.FC<UserCardProps> = ({ name, age, email }) => (
<div>
<h2>{name}</h2>
<p>Возраст: {age}</p>
<p>Email: {email}</p>
</div>
);
Преимущества TypeScript:
Даже при использовании PropTypes или TypeScript иногда требуется дополнительная проверка значений на уровне выполнения:
const UserCard = ({ name, age }) => {
if (typeof name !== 'string' || name.trim() === '') {
throw new Error('Имя пользователя должно быть непустой строкой');
}
if (typeof age !== 'number' || age < 0) {
throw new Error('Возраст должен быть положительным числом');
}
return (
<div>
<h2>{name}</h2>
<p>Возраст: {age}</p>
</div>
);
};
Рекомендации:
Для сложных структур данных удобно применять библиотеки схем, например, Zod или Yup:
import { z } from 'zod';
const userSchema = z.object({
name: z.string().min(1),
age: z.number().nonnegative(),
email: z.string().email().optional(),
});
const UserCard = ({ data }) => {
const parsedData = userSchema.parse(data);
return (
<div>
<h2>{parsedData.name}</h2>
<p>Возраст: {parsedData.age}</p>
<p>Email: {parsedData.email}</p>
</div>
);
};
Преимущества схем:
При работе с MDX важно учитывать источник данных. Лучшие практики включают:
Очистка пользовательских данных:
Использование дефолтных значений:
const UserCard = ({ name = 'Неизвестный', age = 0 }) => { ... }Асинхронная проверка данных при получении с API:
const fetchUser = async () => {
const response = await fetch('/api/user');
const data = await response.json();
return userSchema.parse(data);
};Эти методы позволяют создавать MDX-компоненты, устойчивые к ошибкам входных данных, безопасные и легко поддерживаемые.