背景:由于业务变更需要将业务组件抽离成公共业务组件
转换方式
// import store from '../../store'
// const [state, stateDispatcher] = store.useModel('advance');
import { transform } from './transform';
import models from './models';
const [state, stateDispatcher] = transform(models, 'advance');
transform.ts
import { useState } from 'react';
import { cloneDeep } from 'lodash';
interface ModelType {
state: any;
reducers?: object;
effect?: () => {};
[propName: string]: any;
}
export function transform(model: ModelType, nameSpace?: string) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const { state, reducers, effects } = model;
// eslint-disable-next-line react-hooks/rules-of-hooks
const [_state, _stateDispatcher] = useState(state);
const _mutations = {};
// eslint-disable-next-line guard-for-in
for (const rdc in reducers) {
_mutations[rdc] = function (payload) {
const newState = cloneDeep(_state);
reducers?.[rdc]?.(newState, payload);
if (JSON.stringify(newState) !== JSON.stringify(_state)) _stateDispatcher(newState);
};
}
if (nameSpace) {
_mutations[nameSpace] = _proxy(_mutations);
}
const _actions = effects(_mutations);
const initProxy = {
..._mutations,
..._actions,
};
const _dispatcher = _proxy(initProxy);
return [_state, _dispatcher];
}
// transfer target access to source
function _proxy(sourceObj) {
// eslint-disable-next-line no-param-reassign
return new Proxy(sourceObj, {
get(target, propKey, receiver) {
return Reflect.get(sourceObj, propKey, receiver);
},
set(target, propKey) {
return target[propKey];
},
});
}