npm package: @quarkunlimit/qu-mobx
Description: ## doc
Author: nevermore
Latest version: 1.0.0

# realmerit-mobx

## doc

- createContainer 工厂函数创建上下文

```tsx
class Test {
  count: number;
  constructor() {
    this.count = 0;
    makeAutoObservable(
      this,
      {},
      {
        autoBind: true,
      }
    );
  }
  inc() {
    this.count += 1;
  }
}
const { Provider, useStore } = createContainer(() =>
  useLocalObservable(() => new Test())
);

const Count: React.FC = observer(() => {
  const store = useStore();

  return (
    <div>
      <button type="button" onClick={store.inc}>
        add
      </button>
      <span data-testid="test1">{store.count}</span>
    </div>
  );
});
const Count2: React.FC = observer(() => {
  const store = useStore();
  return (
    <div>
      <span data-testid="test2">{store.count}</span>
    </div>
  );
});
export const App: React.FC = () => {
  return (
    <StrictMode>
      <Provider>
        <Count />
      </Provider>
      <Provider>
        <Count2 />
      </Provider>
    </StrictMode>
  );
};
```

- withRequest 处理 loading 和函数正在运行的 flag

```ts
class Test {
  loadingStore: LoadingStore<'loadingName'>;
  constructor() {
    this.loadingStore = new LoadingStore();
    // this.invoke必须是一个async
    // 第二个参数不填则代表不需要loading
    this.invoke = withRequest(this.invoke, 'loading的key');
  }
  async invoke() {
    // 如果使用promise,则必须return
    return Api.xxx().then(()=>{})

    // 或者用await,推荐使用
    let [err1,res2] = await to(somePromise())
    let [err2,res2] = await to(somePromise())

}
  // 获得loading
  this.loadingStore.get(`loading的key`)
}
```

- 和 NGTable 一起使用

```tsx
class Test {
  tableStore: TableStore;
  constructor() {
    this.tableStore = new TableStore(Api.getData, {
      // rowKey 必传
      rowKey: 'id',
      defaultPageSize: 50,
      currentKey: 'current',
      pageSizeKey: 'pageSize',
      defaultParam: { defaultParam: 'i am defaultParam' },
      // formatResult强制返回total,dataSource的格式
      formatResult: res => {
        return {
          total: res.total,
          dataSource: res.dataSource,
        };
      },
    });
  }
}

// t.tableStore.table => 返回NGTable需要的各种(只读)
// t.tableStore.dataSource => 返回dataSource提供修改

// 同理,`NEForm的Formlist也可以抽成一个hooks`
function useColumns(){
  const store = useStore();
  // 返回一个对象
  return useLocalObservable(()=>({
    // 需要返回一个getter
    get columns(){
      {
        title: 'key',
        dataIndex: 'key',
        key: 'key',
        fixed: 'left'
      },
       {
        title: `客户类型${store.title}`,
        dataIndex: 'customerTypeName',
        key: 'customerTypeName'
      },
    }
  }))

}

const A = observer(props => {
  const store = useStore();
  const {columns} = useColumns()
  return <NGTable {...store.tableStore.table} {columns}={columns}/>;
});
}
```

- 如何在 store 里使用 props

```tsx
class Store {
  propsStore: PropsStore<Type>;
  constructor() {
    this.propsStore = new PropsStore();
    // xxx
  }
}

const A = observer(props => {
  const store = useStore();
  useSyncProps<Props>(store, 'id', props.id);
  // 支持数组使用
  useSyncProps<Props>(store, ['id', 'xxx'], props);

  return <B />;
});

const B = observer(props => {
  const store = useStore();
  return <div>{store.propsStore.props.id}</div>;
});

// 注意 propsStore 只应该做读取操作
// 如果需要托管props 你应该自己维护
```

## 测试覆盖率

```
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files          |     100 |      100 |     100 |     100 |
 src               |     100 |      100 |     100 |     100 |
  utils.ts         |     100 |      100 |     100 |     100 |
 src/enhance       |     100 |      100 |     100 |     100 |
  ...Container.tsx |     100 |      100 |     100 |     100 |
  withRequest.ts   |     100 |      100 |     100 |     100 |
 src/hooks         |     100 |      100 |     100 |     100 |
  useReaction.ts   |     100 |      100 |     100 |     100 |
  useWhen.ts       |     100 |      100 |     100 |     100 |
 ...e/LoadingStore |     100 |      100 |     100 |     100 |
  index.ts         |     100 |      100 |     100 |     100 |
 ...ore/TableStore |     100 |      100 |     100 |     100 |
  index.ts         |     100 |      100 |     100 |     100 |
-------------------|---------|----------|---------|---------|-------------------
```