MDX позволяет смешивать Markdown и JSX, что открывает возможность использовать полноценные React-компоненты прямо внутри документации или контента. Для использования компонентов необходимо импортировать их в MDX-файл, после чего их можно вставлять в любое место документа.
import Alert from './Alert';
<Alert type="warning">
Это предупреждающее сообщение.
</Alert>
В этом примере Alert — это обычный React-компонент. Он
ведет себя так же, как в React-приложении, с полной поддержкой пропсов,
состояния и событий.
MDX полностью поддерживает передачу пропсов в компоненты, включая строковые, числовые, логические значения, объекты и массивы.
<ProductCard
title="Смартфон"
price={29999}
features={['Экран 6.5"', '128GB память', '4G LTE']}
/>
Пропсы обрабатываются React так же, как в обычном приложении. С помощью этого механизма можно создавать динамические и интерактивные элементы внутри статического контента.
Компоненты можно вкладывать друг в друга, создавая сложные структуры прямо в MDX. Это позволяет строить богатый контент с минимальным количеством шаблонного кода.
<Card>
<Card.Header>Заголовок карточки</Card.Header>
<Card.Body>
<p>Описание содержимого.</p>
<Button onCl ick={() => alert('Нажато!')}>Подробнее</Button>
</Card.Body>
</Card>
Вложенность компонентов полностью поддерживается JSX-синтаксисом. Можно использовать условное отображение, массивы и методы массива для генерации контента.
{items.map(item => (
<ListItem key={item.id}>{item.name}</ListItem>
))}
MDX позволяет использовать хуки React и локальное состояние компонентов. Например, можно создать интерактивный счетчик прямо в документе:
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Счетчик: {count}</p>
<button onCl ick={() => setCount(count + 1)}>Увеличить</button>
</div>
);
}
<Counter />
Все функции и состояния работают идентично React-приложению, что делает MDX мощным инструментом для интерактивной документации.
MDX позволяет использовать контексты React для передачи данных через дерево компонентов. Это особенно полезно для темизации, управления состоянием или настройки глобальных параметров.
import { ThemeProvider } from './ThemeContext';
import ThemedButton from './ThemedButton';
<ThemeProvider value={{ color: 'blue' }}>
<ThemedButton>Нажми меня</ThemedButton>
</ThemeProvider>
Компоненты внутри <ThemeProvider> автоматически
получают доступ к значениям контекста через useContext.
С помощью MDX можно динамически загружать компоненты через
React.lazy и Suspense, что снижает начальную
нагрузку и позволяет создавать сложные интерактивные элементы только по
необходимости.
import { Suspense, lazy } from 'react';
const LazyChart = lazy(() => import('./Chart'));
<Suspense fallback={<p>Загрузка графика...</p>}>
<LazyChart data={chartData} />
</Suspense>
Такой подход обеспечивает оптимизацию производительности для больших MDX-документов с множеством интерактивных элементов.
Компоненты могут сочетаться с Markdown-разметкой. Например, можно вставить React-компонент внутрь текста:
Здесь идет обычный текст документации, а ниже — интерактивная форма:
<FormComponent />
MDX автоматически обрабатывает смешанный контент, обеспечивая корректное отображение Markdown и JSX одновременно.
MDX позволяет настроить маппинг тегов Markdown на React-компоненты
через MDXProvider. Это удобно для замены стандартных
элементов, таких как h1, p или a,
на собственные стилизованные компоненты.
import { MDXProvider } from '@mdx-js/react';
import { Heading, Paragraph, Link } from './CustomComponents';
const components = {
h1: Heading,
p: Paragraph,
a: Link,
};
<MDXProvider components={components}>
<Content />
</MDXProvider>
Такой подход позволяет контролировать внешний вид и поведение всех Markdown-элементов в проекте.
React-компоненты в MDX обладают полной функциональностью React, включая пропсы, состояния, хуки, контексты, динамическую загрузку и композицию. Они могут быть встроены прямо в текстовую разметку, комбинируясь с Markdown, что делает MDX идеальным инструментом для создания интерактивной документации и образовательных материалов.