一、简介

React-MVM
这是一个简单的状态管理框架,MVM 分别是 Model、View和Manager的意思。它的作用主要在于:

  • 做数据层和视图层的分离,当然这里的数据层指的是全局数据;
  • 它可以统一化开发模式,降低维护成本,提高开发效率;
  • 用于组件开发时,它是个透明的盒子,这样就避免了常规组件开发碰到一些特殊需求时,需要帮忙添加回调函数,以及黑盒组件数据无法获取等问题。

二、基本概念

1、Model

Model 是用于管理数据状态的,可以用于定义state,设置更新state的updater函数,以及挂载一些handler即处理函数,后续也可以加入ref、hooks等支持,model的使用期望是对应某一块的功能,比如sdk这样的,与自定义的hooks封装相比,只是实现方式不同。

2、View

View 是视图层的入口,通过用 hooks 的方式去获取 Model中的state、updater以及handler等,这样将数据层的副作用抽离出去之后,视图层会看起来更加的干净。

3、Manager

Manager 即入口函数,它的作用是将Model层与View挂载在上面,做好它们之间的关联管理,通过ReactContext的方式将Model数据层的实例挂在顶层,这样View层的任一位置就可以通过这个context获取到model的数据,同时,由于model实例化之后并不会变化,因此完全不用担心context会导致其往下的视图层重新渲染。

图1:MVM模型图
image.png
图1

三、示例

1、步骤一:设置Model

createStore是用于构建model所需要的store的,构建完成之后,亦可以在model层中的handlers使用 store 去获取;

createModel的返回值必须包含两个,namestorename是用来定义该model构建之后,在 chrome 浏览器中Redux devtools展示的名称,以及Manager中绑定的名称,storecreateStore构建出来的store

  1. // ./_model.ts
  2. import { createStore, createModel } from '@xxx/react-mvm';
  3. const model = createModel(() => {
  4. let name = 'model';
  5. let initialState: State = {
  6. count: 0,
  7. };
  8. let updaters = {
  9. updateCount: (state: State, count: number) => {
  10. state.count = count;
  11. },
  12. };
  13. let store = createStore({
  14. name,
  15. initialState,
  16. updaters,
  17. });
  18. let fetchCount = async () => {
  19. let state = store.getState();
  20. let updaters = store.updaters;
  21. return;
  22. };
  23. return {
  24. store,
  25. handlers: {
  26. fetchCount,
  27. },
  28. };
  29. });
  30. export default model;
  31. type State = {
  32. count: number;
  33. };

2、步骤二:设置View

  1. // ./_view.tsx
  2. import React from 'react';
  3. import model from './_model';
  4. export default function View() {
  5. const state = model.useState();
  6. const updaters = model.useUpdaters();
  7. const handlers = model.useHandlers();
  8. const handleClickA = () => {
  9. updaters.updateCount(state.count + 1);
  10. handlers.fetchCount();
  11. };
  12. return (
  13. <div>
  14. <p>
  15. {state.count}
  16. <button style={{ marginLeft: 10 }} onClick={handleClick}>
  17. +
  18. </button>
  19. </p >
  20. </div>
  21. );
  22. }

3、步骤三:设置Manager

Manager层则是很简单的将viewmodel挂到它上面即可,此外,还可以在preload中做一些数据的预处理,同时,需要设置LoadView,在preload执行完之前,做一个loading状态的渲染。

  1. // ./index.ts
  2. import { manager } from '@xxx/react-mvm';
  3. import view from './_view';
  4. import model from './_model';
  5. let Page = manager({
  6. View: view,
  7. models: [model],
  8. LoadView: null,
  9. preload: async ({ models }) => {
  10. let [localModel] = models;
  11. let updaters = localModel.store.updaters;
  12. // ...
  13. },
  14. });
  15. export default Page;