import { ReactElement } from 'react';
/**
* Абстрактный класс для рендеринга UI компонентов
*/
export abstract class UIRenderer {
/**
* Рендер компонента
*/
abstract render(component: ReactElement): void;
/**
* Рендер UI компонента
*/
abstract renderComponent(component: ReactElement): void;
/**
* Очистка UI компонентов
*/
abstract clearComponents(): void;
/**
* Очистка всех компонентов
*/
abstract clear(): void;
/**
* Уничтожение рендерера и освобождение ресурсов
*/
abstract destroy(): void;
/**
* Проверка, инициализирован ли рендерер
*/
abstract isInitialized(): boolean;
}
import React, { ReactElement } from 'react';
import { createRoot, Root } from 'react-dom/client';
import { UIRenderer } from './UIRenderer';
/**
* React реализация рендерера UI компонентов
*/
export class ReactRenderer extends UIRenderer {
protected reactRoot: Root | null = null;
protected container: HTMLElement;
constructor(container: HTMLElement) {
super();
this.container = container;
}
/**
* Инициализация React рендера
*/
private initializeReact(): void {
if (!this.reactRoot) {
this.reactRoot = createRoot(this.container);
}
}
/**
* Рендер React компонента
*/
render(component: React.ReactElement): void {
if (!this.reactRoot) {
this.initializeReact();
}
this.reactRoot?.render(component);
}
/**
* Очистка React компонентов
*/
clear = () => {
const root = this.reactRoot;
if (!root) return;
this.reactRoot = null;
requestAnimationFrame(() => root.unmount());
};
/**
* Проверить, инициализирован ли React
*/
isInitialized(): boolean {
return this.reactRoot !== null;
}
/**
* Уничтожение React рендерера
*/
destroy(): void {
this.clear();
}
/**
* Рендер UI компонента
*/
renderComponent(component: ReactElement): void {
this.render(component);
}
/**
* Очистка UI компонентов
*/
clearComponents(): void {
this.clear();
}
}