UNPKG

@mic-rexjs/usecases-react

Version:

React-based solution for use usecases of Clean Architecture

61 lines (60 loc) 2.9 kB
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]); });