ice中redux转useState

唐俊楚
2023-12-01

背景:由于业务变更需要将业务组件抽离成公共业务组件

转换方式

// 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];
    },
  });
}

 类似资料: