@mic-rexjs/usecases-react
Version:
React-based solution for use usecases of Clean Architecture
61 lines (60 loc) • 2.9 kB
JavaScript
import { useCreation, useLatest } from 'ahooks';
import { useContext as useContextValue } from 'react';
import { useConstantFn } from '../useConstantFn';
import { useProvider } from '../useProvider';
import { initEntityReducers } from '../../methods/initEntityReducers';
import { useContext } from '../useContext';
import { useIsRenderingRef } from '../useIsRenderingRef';
import { useArgumentTypes } from '../useArgumentTypes';
import { useStatuses } from '../useStatuses';
import { Statuses } from '../../enums/Statuses';
import { useEntity } from '../useEntity';
import { useContextualItem } from '../useContextualItem';
import { cacheCalls } from '../../methods/cacheCalls';
import { useCompareDeps } from '../useCompareDeps';
import { captureCalls } from '../../methods/captureCalls';
import { useFullArguments } from '../useFullArguments';
export const useUseCase = ((...args) => {
const isRenderingRef = useIsRenderingRef();
const argumentTypes = useArgumentTypes(args);
const fullArguments = useFullArguments(args, argumentTypes);
const [unsafeEntity, unsafeUsecase, options, deps] = fullArguments;
const unkownUsecase = useConstantFn(unsafeUsecase);
const usecase = unkownUsecase;
const entityUseCase = unkownUsecase;
const context = useContext(unkownUsecase, argumentTypes);
const contextValue = useContextValue(context);
const entityContextValue = contextValue;
const statuses = useStatuses(argumentTypes, contextValue);
const optionsRef = useLatest(options);
const depsKey = useCompareDeps(deps);
const { reducers: contextReducers = null } = contextValue || {};
const { store: contextStore = null } = entityContextValue || {};
const [entity, store] = useEntity(statuses, unsafeEntity, contextStore, options);
const reducers = useContextualItem(contextReducers, statuses, () => {
const opts = captureCalls(options, (key, callArgs) => {
return optionsRef.current[key]?.(...callArgs);
});
if ((statuses & Statuses.EntityEnabled) !== Statuses.EntityEnabled) {
return usecase(opts);
}
const hookOptions = opts;
return initEntityReducers(entityUseCase, store, hookOptions);
}, depsKey);
const Provider = useProvider(statuses, context, store, reducers);
return useCreation(() => {
if ((statuses & Statuses.EntityEnabled) !== Statuses.EntityEnabled) {
return reducers;
}
const rootEnabled = (statuses & Statuses.RootEnabled) === Statuses.RootEnabled;
const cachedReducers = cacheCalls(reducers, {
onShouldCache() {
return isRenderingRef.current;
},
});
if (rootEnabled) {
return [entity, cachedReducers, Provider];
}
return [entity, cachedReducers];
}, [statuses, entity, reducers, Provider, isRenderingRef]);
});