react+mobx 编写 Async装饰器

使用

   // indexStore.js
   import axios from "axios";
   import { from } from "rxjs";
   import { map } from "rxjs/operators";

  @util.Async(from(axios("http://localhost:5000/test")).pipe(map(v => v.data.users)))
  @util.isEmpty(true)
  // @observable  // 不需要observer
  list;

实现


import { set } from "mobx";
import * as u from "lodash";

/**
 * * async: false => data => isData
 * * async: true => data => isData$
 */
export const isEmpty = (async = false) => {
  return function(target, key) {
    let opt = async ? `is${u.upperFirst(key)}$` : `is${u.upperFirst(key)}`;
    Object.defineProperty(target, opt, {
      get: function proxyGetter() {
        const k = async ? `${key}$` : key;
        return !u.isEmpty(this[k]);
      },
      enumerable: true,
      configurable: true,
    });
  };
};

// list=> list$
export const Async = (fn$, initData = null) => {
  return function(target, key) {
    set(target, {
      [`${key}$`]: initData,
    });
    fn$.subscribe(
      v => {
        set(target, {
          [`${key}$`]: v,
        });
      },
      err => console.error(err),
      () => {
        /* done */
      },
    );
  };
};

组件

const INDEXSTORE = "indexStore";

@inject(INDEXSTORE)
@observer
class Test extends Component {
  render() {
    const { indexStore } = this.props;
    return (
      <>
        {indexStore.isList$ && (
          <>
            <h2>list</h2>
            <ul>
              {indexStore.list$.map(el => (
                <li key={el}>{el}</li>
              ))}
            </ul>
          </>
        )}
      </>
    );
  }
}

猜你喜欢

转载自www.cnblogs.com/ajanuw/p/10065029.html