Передача props компонентам

MDX сочетает в себе возможности Markdown и JSX, что позволяет внедрять React-компоненты прямо в Markdown-документы. Ключевой механизм взаимодействия с компонентами в MDX — это передача props. 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>
);

Использование вложенных компонентов через props

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

Props можно вычислять прямо в MDX с помощью JavaScript-выражений:

import { getColor } from './utils'

<MyButton color={getColor('primary')} disabled={false}>
  Нажми меня
</MyButton>

Это позволяет создавать компоненты, полностью управляемые логикой приложения, прямо внутри Markdown-документа.


Расширение стандартных HTML-элементов

MDX позволяет оборачивать стандартные элементы HTML в кастомные компоненты с поддержкой props:

<CustomHeading level={2}>Заголовок второго уровня</CustomHeading>

Реализация может быть такой:

export const CustomHeading = ({ level, children }) => {
  const Tag = `h${level}`;
  return <Tag>{children}</Tag>;
};

Это даёт гибкость при создании документации или контента с динамически изменяемыми заголовками.


Использование дефолтных props

Как и в 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 />} />

Взаимодействие с Markdown-контентом

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.