withViewModel.tsx
Назначение файла
Модуль предоставляет HOC withViewModel(), который создает view-model и передает ее в React-компонент через prop viewModel.
Общая информация
withViewModel() ориентирован на MVVM-сценарии, где визуальный компонент ожидает объект viewModel и, как правило, читает состояние через useAtoms(). Модуль также экспортирует withViewModelImpl(), который используется как внутренняя реализация и может быть полезен для расширений.
Концептуальная архитектура
Модуль оборачивает useController() типизированной прослойкой для ViewModelDeclaration.
withViewModel()принимает декларацию view-model и возвращает фабрику HOC.withViewModelImpl()строит компонент-обертку, отделяетchildrenот остальных props и передает оставшиеся props вuseController().- Результирующий компонент рендерит исходный
ViewComponent, пробрасывая:children, исходные props и созданныйviewModel.
Такой дизайн позволяет сохранить строгую типизацию InferViewModelProps и избавляет пользователя от ручного приведения типов в каждом представлении.
Описание публичного API
withViewModel<TViewModel>(viewModelDeclaration)
viewModelDeclaration: декларация view-model, совместимая сViewControllerContext<InferViewModelProps<TViewModel>>.- Возвращает функцию, которая принимает компонент с prop
viewModelи создает HOC с автоматически выведенными props view-model.
withViewModelImpl(viewModelDeclaration, ViewComponent)
- Внутренний помощник для построения HOC.
- Принимает декларацию view-model и React-компонент.
- Возвращает компонент, создающий
viewModelчерезuseController().
Примеры использования
tsx
import React from 'react';
import { declareViewModel, readonlyAtom } from '@nrgyjs/core';
import { useAtoms, withViewModel } from '@nrgyjs/react';
const CounterViewModel = declareViewModel(({ scope, view }) => {
const value = scope.atom(view.props.initialValue());
return {
state: { value: readonlyAtom(value) },
increase: () => value.update((prev) => prev + 1),
};
});
const Counter = withViewModel(CounterViewModel)(({ viewModel }) => {
const { value } = useAtoms(viewModel.state);
return <button onClick={viewModel.increase}>{value}</button>;
});