UNPKG

@mic-rexjs/usecases-react

Version:

React-based solution for use usecases of Clean Architecture

101 lines 3.38 kB
import { useConstantEntityReducers } from '../useConstantEntityReducers'; import { useExec } from '../useExec'; import { useLatest, useMemoizedFn, useUnmount, useUpdate, useUpdateEffect } from 'ahooks'; import { useEffect, useRef } from 'react'; import { Statuses } from '../../enums/Statuses'; import { triggerWatchers } from '../../methods/triggerWatchers'; import { valueUseCase } from '../../usecases/valueUseCase'; export const useEntity = (entityArg, store, reducers, statuses, options) => { const update = useUpdate(); const isFunction = typeof entityArg === 'function'; const entity = store.value; const isFirstRef = useRef(true); const optionsRef = useLatest(options); const prevEntityRef = useRef(entity); const entityEnabled = (statuses & Statuses.EntityEnabled) === Statuses.EntityEnabled; const entityRootEnabled = (statuses & Statuses.EntityRootEnabled) === Statuses.EntityRootEnabled; const bindEntity = reducers.bindEntity, unbindEntity = reducers.unbindEntity; const _useConstantEntityRed = useConstantEntityReducers(entityArg, valueUseCase), isValueChanged = _useConstantEntityRed.isValueChanged, recordValue = _useConstantEntityRed.recordValue; const onTriggerWatchers = useMemoizedFn((newEntity, oldEntity) => { const watch = optionsRef.current.watch; if (!watch) { return; } triggerWatchers(watch, newEntity, oldEntity); }); const onEntityChange = useMemoizedFn((newEntity, oldEntity) => { const onChange = optionsRef.current.onChange; prevEntityRef.current = newEntity; onTriggerWatchers(newEntity, oldEntity); onChange === null || onChange === void 0 || onChange(newEntity, oldEntity); if (!entityRootEnabled) { return; } update(); }); const onValueChange = useMemoizedFn(() => { if (!entityEnabled) { return; } const prevEntity = prevEntityRef.current; if (entity === prevEntity) { return; } prevEntityRef.current = entity; onTriggerWatchers(entity, prevEntity); }); useExec(() => { const isFirst = isFirstRef.current; isFirstRef.current = false; if (!entityRootEnabled) { return; } if (isFirst) { // 这里不要修改 `entity`,因为 `useUseCase` 有初始化 `entity` 的逻辑 bindEntity === null || bindEntity === void 0 || bindEntity(); } if (isFunction) { return; } const isChanged = isValueChanged(entityArg); if (!isChanged) { return; } recordValue(entityArg); store.disableWatchers(); // 执行同步操作 store.setValue(entityArg); store.enableWatchers(); }); /** * 需要马上 `watch`,因为 `useEffect` 在子组件内优先执行, * 如果使用了 `setEntity` 则无法监控到变化 */ useExec(() => { if (!entityEnabled) { return; } store.watch(onEntityChange); }, [entityEnabled, store, onEntityChange]); /** * 在变化时候,组件更新前,使用 `unwatch` */ useEffect(() => { return () => { store.unwatch(onEntityChange); }; }, [entityEnabled, store, onEntityChange]); useUnmount(() => { if (!entityRootEnabled) { return; } unbindEntity === null || unbindEntity === void 0 || unbindEntity(); }); useUpdateEffect(() => { onValueChange(); }, [entity, onValueChange]); return store.value; };