useController.ts
Назначение файла
Модуль содержит хук useController(), который создает и сопровождает экземпляр контроллера или view-model внутри React-компонента.
Общая информация
useController() является основной точкой интеграции между React и @nrgyjs/core. Хук принимает декларацию контроллера или view-model, при необходимости передает в нее props представления, а затем синхронизирует жизненный цикл созданного экземпляра с жизненным циклом React-компонента.
Концептуальная архитектура
Работа хука строится следующим образом:
- Из
NrgyControllerExtensionизвлекаются React-специфичныеExtensionParamsProvider. - Для текущих props создается
ViewProxyчерезcreateViewProxy(). - К списку provider'ов добавляется
provideView(view), после чего создается экземпляр контроллера:new declaration(providers). - Экземпляр и связанный
ViewProxyсохраняются вuseRef(), чтобы не пересоздавать их на каждом рендере. - В отдельном
useEffect()хук передает новые props вview.update(props). - В lifecycle-эффекте вызываются
view.mount()при монтировании иview.destroy()вместе сcontroller.destroy()при размонтировании или замене декларации.
Дополнительно хук повторно вызывает extension-provider'ы на последующих рендерах, чтобы сохранить корректный порядок React-хуков внутри расширений.
Описание публичного API
useController<TContext, TService>(declaration): TService
declaration: декларация контроллера или view-model без обязательных view-props.- Возвращает созданный экземпляр сервиса
TService.
useController<TContext, TService, TProps>(declaration, props): TService
declaration: декларация контроллера или view-model, зависящая от props представления.props: объект props, который передается вViewProxy.- Возвращает экземпляр сервиса
TService.
Примеры использования
tsx
import React from 'react';
import { declareController, withView } from '@nrgyjs/core';
import { useController } from '@nrgyjs/react';
const GreetingController = declareController()
.extend(withView<{ name: string }>())
.apply(({ view }) => ({
title: () => `Hello, ${view.props.name()}!`,
}));
export function Greeting(props: { name: string }) {
const controller = useController(GreetingController, props);
return <h1>{controller.title()}</h1>;
}