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 компоненты могут использовать контекст как обычные React-компоненты. Для получения данных применяются два подхода:
useContextimport 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 поддерживает импорт и использование 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-компоненты автоматически реагируют на обновления контекста, что делает интерфейс живым и интерактивным.
useContext для упрощения кода в
функциональных компонентах.Контекст в MDX открывает возможности для модульной и реактивной организации контента, позволяя поддерживать масштабируемые и настраиваемые учебные материалы.