Передача данных через контекст

MDX позволяет комбинировать JSX и Markdown, что открывает возможности для динамического управления содержимым. Одной из ключевых концепций является передача данных через контекст, которая позволяет компонентам глубоко внутри дерева получать данные без необходимости прокидывать их через все промежуточные компоненты.


Создание контекста

Для работы с контекстом используется стандартный API React: React.createContext(). Контекст создается с указанием значения по умолчанию, которое будет использоваться, если компонент, потребляющий контекст, окажется вне провайдера.

import React, { createContext } from 'react';

export const ThemeContext = createContext({ color: 'black', fontSize: 16 });

Здесь ThemeContext содержит объект с настройками темы. По умолчанию цвет текста — черный, размер шрифта — 16 пикселей.


Провайдер контекста

Чтобы данные контекста были доступны компонентам внутри MDX, используется провайдер: Context.Provider. Провайдер оборачивает часть дерева компонентов и передает им значение контекста через проп value.

import { ThemeContext } from './ThemeContext';

function App({ children }) {
  const theme = { color: 'blue', fontSize: 18 };

  return (
    <ThemeContext.Provider value={theme}>
      {children}
    </ThemeContext.Provider>
  );
}

export default App;

В данном примере все компоненты внутри App получают доступ к объекту theme без необходимости передавать его через пропсы.


Потребление контекста в MDX

В MDX компоненты могут использовать контекст как обычные React-компоненты. Для получения данных применяются два подхода:

Хук useContext

import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemedText({ children }) {
  const theme = useContext(ThemeContext);

  return <p style={{ color: theme.color, fontSize: theme.fontSize }}>{children}</p>;
}

export default ThemedText;

useContext извлекает текущее значение контекста, установленное ближайшим провайдером выше в дереве. Это позволяет динамически изменять стили и содержимое в зависимости от контекста.

Компонент Context.Consumer

Альтернативный способ — использование Consumer, что полезно для вложенных выражений:

import { ThemeContext } from './ThemeContext';

function ThemedText({ children }) {
  return (
    <ThemeContext.Consumer>
      {theme => <p style={{ color: theme.color, fontSize: theme.fontSize }}>{children}</p>}
    </ThemeContext.Consumer>
  );
}

Внутри функции-ребенка Consumer доступно текущее значение контекста.


Передача данных между компонентами MDX

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

import ThemedText from './ThemedText';
import { ThemeContext } from './ThemeContext';

<ThemeContext.Provider value={{ color: 'red', fontSize: 20 }}>
  <ThemedText>Это текст с контекстной темой</ThemedText>
</ThemeContext.Provider>

Даже если ThemedText находится глубоко в структуре MDX, оно будет использовать значение контекста, заданное провайдером.


Динамическая модификация контекста

Контекст можно изменять в зависимости от состояния компонента, что позволяет создавать интерактивные MDX-документы:

import React, { useState } from 'react';
import { ThemeContext } from './ThemeContext';
import ThemedText from './ThemedText';

function InteractiveTheme() {
  const [theme, setTheme] = useState({ color: 'black', fontSize: 16 });

  return (
    <ThemeContext.Provider value={theme}>
      <button onCl ick={() => setTheme({ color: 'green', fontSize: 22 })}>
        Изменить тему
      </button>
      <ThemedText>Текст с изменяемой темой</ThemedText>
    </ThemeContext.Provider>
  );
}

export default InteractiveTheme;

MDX-компоненты автоматически реагируют на обновления контекста, что делает интерфейс живым и интерактивным.


Сценарии применения

  1. Темизация — передача информации о цветовой схеме, шрифтах, отступах.
  2. Локализация — контекст может содержать текущий язык и функции перевода.
  3. Настройки пользователя — тема, режим просмотра, скрытие/отображение элементов.
  4. Глобальные состояния — например, авторизация, состояние корзины, фильтры для контента.

Рекомендации по структуре MDX с контекстом

  • Создавать отдельные файлы для контекста и провайдера.
  • Разделять логические блоки: контекст, провайдер, потребляющие компоненты.
  • Использовать useContext для упрощения кода в функциональных компонентах.
  • Оборачивать только необходимую часть дерева в провайдер, чтобы минимизировать ререндеринг.

Контекст в MDX открывает возможности для модульной и реактивной организации контента, позволяя поддерживать масштабируемые и настраиваемые учебные материалы.