@mic-rexjs/usecases-react
Version:
React-based solution for use usecases of Clean Architecture
82 lines • 3.41 kB
JavaScript
import { useContextualItem } from '../useContextualItem';
import { createEntity, createEntityReducers, EntityStore } from '@mic-rexjs/usecases';
import { useContext, useRef } from 'react';
import { Statuses } from '../../enums/Statuses';
import { entityRuntimeUseCase } from '../../usecases/entityRuntimeUseCase';
import { valueUseCase } from '../../usecases/valueUseCase';
export const useStore = function (entityArg, context, statuses, options) {
let deps = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
const storeRef = useRef(null);
const createEntityListRef = useRef([]);
const entityRootEnabled = (statuses & Statuses.EntityRootEnabled) === Statuses.EntityRootEnabled;
const contextValue = useContext(context);
const _ref = contextValue || {},
_ref$store = _ref.store,
contextStore = _ref$store === void 0 ? null : _ref$store;
const initStore = () => {
const isFunction = typeof entityArg === 'function';
if (!isFunction) {
return new EntityStore(entityArg);
}
let index = 0;
const currentStore = storeRef.current;
const _ref2 = currentStore || {},
currentEntity = _ref2.value;
const prevCreateEntityList = createEntityListRef.current;
const store = new EntityStore(currentEntity);
const createEntityList = [];
const _valueUseCase = valueUseCase(),
isObjectValue = _valueUseCase.isObjectValue,
matchValue = _valueUseCase.matchValue;
const _createEntityReducers = createEntityReducers(store, entityRuntimeUseCase, {
onInit(currentValue) {
return entityArg(currentValue);
},
onCreate(newEntity, oldEntity) {
const currentIndex = index;
const isObject = isObjectValue(oldEntity);
const isArray = isObject && Array.isArray(oldEntity);
index++;
createEntityList[currentIndex] = newEntity;
if (!isObject || isArray) {
return createEntity(oldEntity, newEntity);
}
const descriptors = {};
const prevEntity = prevCreateEntityList[currentIndex];
matchValue(prevEntity, newEntity, key => {
const descriptor = Object.getOwnPropertyDescriptor(newEntity, key) || null;
if (descriptor === null) {
return;
}
descriptors[key] = descriptor;
});
return createEntity(oldEntity, Object.defineProperties({}, descriptors));
},
onGenerate(entity, result) {
if (typeof result === 'undefined') {
return [entity, result];
}
const newResult = createEntity(entity, result);
// 不能用 `store.value`,因为可能存在异步,异步更新是需要触发组件更新的
store.setValue(newResult);
return [newResult, result];
},
onReturn(result) {
// 不能用 `store.value`,因为可能存在异步,异步更新是需要触发组件更新的
store.setValue(result);
return result;
}
}),
initEntity = _createEntityReducers.initEntity;
initEntity();
storeRef.current = store;
createEntityListRef.current = createEntityList;
return store;
};
return useContextualItem(contextStore, statuses, () => {
if (!entityRootEnabled) {
return new EntityStore(null);
}
return initStore();
}, deps);
};