Микроприложения представляют собой независимые модули, которые совместно формируют целостное приложение. Одной из ключевых задач при работе с ними является обеспечение эффективного обмена данными между отдельными компонентами, особенно когда они изолированы и развиваются независимо. Preact предоставляет несколько инструментов и подходов для организации такой коммуникации.
Для связи микроприложений можно применять глобальное состояние,
управляемое библиотеками вроде Redux,
Zustand или встроенными средствами Preact
(useContext). Такой подход позволяет хранить единое
состояние, которое доступно любому компоненту, подключенному к
хранилищу.
Пример с Preact Context:
import { h } from 'preact';
import { createContext } from 'preact';
import { useContext, useState } from 'preact/hooks';
const AppContext = createContext();
export const AppProvider = ({ children }) => {
const [sharedData, setSharedData] = useState({ user: null });
return (
<AppContext.Provider value={{ sharedData, setSharedData }}>
{children}
</AppContext.Provider>
);
};
export const useAppContext = () => useContext(AppContext);
Каждое микроприложение может подключаться к AppContext и
получать либо обновлять состояние:
import { useAppContext } from './AppProvider';
const UserProfile = () => {
const { sharedData, setSharedData } = useAppContext();
return (
<div>
<p>Пользователь: {sharedData.user?.name || 'Гость'}</p>
<button onCl ick={() => setSharedData({ user: { name: 'Иван' } })}>
Войти
</button>
</div>
);
};
Ключевой момент: контекст удобен для данных, которые часто изменяются и должны быть доступны во многих микроприложениях.
Для более слабосвязанных микроприложений рекомендуется использовать кастомные события DOM. Этот подход минимизирует зависимость между модулями и подходит для динамического внедрения компонентов.
Пример отправки и обработки события:
// Микроприложение A
const sendMessage = () => {
const event = new CustomEvent('userLoggedIn', { detail: { name: 'Иван' } });
window.dispatchEvent(event);
};
// Микроприложение B
window.addEventListener('userLoggedIn', (e) => {
console.log('Пользователь вошёл:', e.detail.name);
});
Преимущества:
Недостатки:
Шина событий — это паттерн, который создаёт централизованное место
для обмена событиями между микроприложениями. В Preact её можно
реализовать с помощью объекта EventTarget или сторонних
библиотек.
Пример реализации Event Bus:
class EventBus extends EventTarget {
emit(event, detail) {
this.dispatchEvent(new CustomEvent(event, { detail }));
}
on(event, callback) {
this.addEventListener(event, callback);
}
off(event, callback) {
this.removeEventListener(event, callback);
}
}
export const bus = new EventBus();
Использование в микроприложениях:
// Микроприложение A
import { bus } from './EventBus';
bus.emit('themeChanged', { theme: 'dark' });
// Микроприложение B
import { bus } from './EventBus';
bus.on('themeChanged', (e) => {
console.log('Новая тема:', e.detail.theme);
});
Преимущества:
Когда микроприложения находятся в одной иерархии компонентов, часто проще использовать props для передачи данных. Такой подход минимизирует использование глобального состояния и сохраняет реактивность Preact.
const ChildApp = ({ user }) => <p>Пользователь: {user.name}</p>;
const ParentApp = () => {
const user = { name: 'Иван' };
return <ChildApp user={user} />;
};
Ключевой момент: props подходят для тесно связанных компонентов, но неэффективны для обмена данными между независимыми микроприложениями.
useState,
useEffect, useContext) обеспечивают
реактивность и удобную подписку на данные между модулями.Эффективная коммуникация между микроприложениями в Preact строится на комбинировании глобального состояния, событийной шины и props, с учётом степени изоляции модулей и частоты обновления данных. Такой подход обеспечивает масштабируемость, модульность и простоту поддержки больших приложений.