@mic-rexjs/usecases-react
Version:
React-based solution for use usecases of Clean Architecture
50 lines (49 loc) • 1.98 kB
JavaScript
import { useEffect } from 'react';
import { EntityStore } from '@mic-rexjs/usecases';
import { Statuses } from '../../enums/Statuses';
import { useContextualItem } from '../useContextualItem';
import { useCreation, useLatest, useMemoizedFn, useUpdate } from 'ahooks';
import { triggerWatchers } from '../../methods/triggerWatchers';
import { useRuntimeEntity } from '../useRuntimeEntity';
export const useEntity = (statuses, entityArg, contextStore, options) => {
const update = useUpdate();
const optionsRef = useLatest(options);
const contextEntity = (contextStore ? contextStore.value : null);
const entityEnabled = (statuses & Statuses.EntityEnabled) === Statuses.EntityEnabled;
const entityRootEnabled = (statuses & Statuses.EntityRootEnabled) === Statuses.EntityRootEnabled;
const store = useContextualItem(contextStore, statuses, () => {
if (!entityRootEnabled) {
return new EntityStore(null);
}
const isFunction = typeof entityArg === 'function';
return new EntityStore(isFunction ? entityArg() : entityArg);
});
const runtimeEntity = useRuntimeEntity(store, entityArg, contextEntity, statuses);
const onEntityChange = useMemoizedFn((newEntity, oldEntity) => {
const { onChange, watch } = optionsRef.current;
if (watch) {
triggerWatchers(watch, newEntity, oldEntity);
}
onChange?.(newEntity, oldEntity);
if (!entityRootEnabled) {
return;
}
update();
});
if (entityRootEnabled) {
// 执行同步操作
store.value = runtimeEntity;
}
useEffect(() => {
if (!entityEnabled) {
return;
}
store.watch(onEntityChange);
return () => {
store.unwatch(onEntityChange);
};
}, [entityEnabled, store, onEntityChange]);
return useCreation(() => {
return [runtimeEntity, store];
}, [runtimeEntity, store]);
};