MDX сочетает в себе возможности Markdown и JSX, что позволяет внедрять React-компоненты прямо в Markdown-документы. Ключевой механизм взаимодействия с компонентами в MDX — это передача props. Props позволяют настраивать поведение компонентов и передавать им данные из внешнего контекста.
В MDX компоненты можно использовать так же, как в JSX. Передача props происходит через синтаксис атрибутов:
<MyButton color="blue" size="large">Нажми меня</MyButton>
В этом примере:
MyButton — React-компонент, импортированный в
MDX-файл.color и size — props, доступные внутри
компонента.Нажми меня) передаётся как
children.Компонент может принимать как примитивные значения (строки, числа, булевы значения), так и объекты и функции:
<MyAlert type="warning" dismissible={true} onCl ose={() => console.log('Закрыто')}>
Внимание! Ошибка при загрузке данных.
</MyAlert>
Здесь:
dismissible — булево значение.onClose — функция обратного вызова, которая выполняется
при закрытии компонента.Для передачи сложных данных используется синтаксис фигурных скобок
{}:
<MyList items={['Яблоко', 'Банан', 'Апельсин']} />
Внутри компонента MyList можно обойти массив через
map и отобразить каждый элемент:
export const MyList = ({ items }) => (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
MDX позволяет передавать компоненты как props, что особенно полезно для построения настраиваемых UI-блоков:
<Card header={<CardHeader title="Привет" />} footer={<CardFooter />}>
Содержимое карточки
</Card>
Внутри компонента Card можно рендерить переданные
компоненты:
export const Card = ({ header, footer, children }) => (
<div className="card">
{header && <div className="card-header">{header}</div>}
<div className="card-body">{children}</div>
{footer && <div className="card-footer">{footer}</div>}
</div>
);
Props можно вычислять прямо в MDX с помощью JavaScript-выражений:
import { getColor } from './utils'
<MyButton color={getColor('primary')} disabled={false}>
Нажми меня
</MyButton>
Это позволяет создавать компоненты, полностью управляемые логикой приложения, прямо внутри Markdown-документа.
MDX позволяет оборачивать стандартные элементы HTML в кастомные компоненты с поддержкой props:
<CustomHeading level={2}>Заголовок второго уровня</CustomHeading>
Реализация может быть такой:
export const CustomHeading = ({ level, children }) => {
const Tag = `h${level}`;
return <Tag>{children}</Tag>;
};
Это даёт гибкость при создании документации или контента с динамически изменяемыми заголовками.
Как и в React, в MDX-компонентах можно задавать значения props по умолчанию:
export const MyButton = ({ color = 'gray', size = 'medium', children }) => (
<button className={`${color} ${size}`}>{children}</button>
);
Если в MDX-файле пропсы не передаются, компонент автоматически использует дефолтные значения:
<MyButton>Стандартная кнопка</MyButton>
MDX часто используется вместе с системами темизации и контекстов.
Пропсы можно комбинировать с React.Context для передачи
глобальных настроек:
import { ThemeContext } from './ThemeContext';
export const ThemedButton = ({ children }) => {
const theme = React.useContext(ThemeContext);
return <button style={{ backgroundColor: theme.primary }}>{children}</button>;
};
В MDX:
<ThemedButton>Кнопка в теме</ThemedButton>
Props в этом случае остаются полезными для дополнительных локальных настроек (например, размера или состояния disabled), дополняя глобальный контекст.
MDX позволяет передавать функции обработчиков событий так же, как в обычном React:
<MyInput onCha nge={(e) => console.log(e.target.value)} />
Компонент может использовать этот проп для выполнения логики при изменении состояния:
export const MyInput = ({ onChange }) => (
<input type="text" onCha nge={onChange} />
);
Компоненты MDX полностью поддерживают деструктуризацию и работу с именованными props:
export const Badge = ({ text, variant = 'info', icon }) => (
<span className={`badge badge-${variant}`}>
{icon && <span className="icon">{icon}</span>}
{text}
</span>
);
В MDX:
<Badge text="Новый" variant="success" icon={<CheckIcon />} />
MDX позволяет передавать props, комбинируя их с содержимым Markdown. Например:
<Callout type="warning">
**Внимание:** использование устаревших API может вызвать ошибки.
</Callout>
Внутри компонента можно использовать children как
React-элементы, сохраняя разметку Markdown:
export const Callout = ({ type, children }) => (
<div className={`callout callout-${type}`}>
{children}
</div>
);
Это делает MDX мощным инструментом для создания документации, учебников и блогов с динамическими компонентами, полностью управляемыми через props.