用 easy-model 重构一个列表页后,我把页面代码砍成了“只负责渲染”

5 阅读1分钟

这篇文章不聊概念,直接聊一个常见页面:列表页(搜索、分页、加载)。

我之前的写法是很多人熟悉的模式:

  • 页面里放多个 useState
  • useEffect 里拉数据
  • 搜索、分页、重置交织在一起
  • loading 再单独维护一套

结果是:需求稍一变化,页面就开始变“脆”。


重构目标

我只做一件事:把“业务动作”从页面拿出来,收进模型。

模型层

class ListModel {
  items: { id: number; name: string }[] = [];
  keyword = "";
  page = 1;
  pageSize = 10;
  total = 0;

  changeKeyword(v: string) {
    this.keyword = v;
    this.page = 1;
  }

  changePage(p: number) {
    this.page = p;
  }

  @loader.load(true)
  async load() {
    // 调接口,更新 items/total
  }
}

页面层

function ListPage() {
  const model = useModel(ListModel, []);
  const { isLoading } = useLoader();

  useEffect(() => {
    model.load();
  }, [model.page, model.keyword]);

  return (
    <>
      <input value={model.keyword} onChange={e => model.changeKeyword(e.target.value)} />
      <button onClick={() => model.load()} disabled={isLoading(model.load)}>
        刷新
      </button>
      {/* 表格和分页渲染 */}
    </>
  );
}

重构后最明显的变化

  1. 页面变“薄”了:只剩渲染和事件绑定
  2. 业务规则集中:翻页、筛选、重置逻辑都在模型里
  3. loading 统一:不再手写多个 isLoadingXxx
  4. 测试更直接:模型可脱离 React 单测

这类重构什么时候最值

  • 需求还在持续变化
  • 页面逻辑已经不止“展示数据”
  • 多人协作导致同一页反复改坏

如果只是一次性小页面,没必要上复杂方案。
但只要页面会长期演进,模型化几乎都会回本。


给正在重构的你一个建议

不要“全页一次性重写”,而是先抽三个动作:

  • changeKeyword
  • changePage
  • load

先把这三个放进模型,页面复杂度会立刻下降一个台阶。


仓库地址:
GitHub: github.com/ZYF93/easy-…
npm: www.npmjs.com/package/@e7…

如果你愿意,我下一篇可以按“用户中心页”再给一个更复杂的拆分模板(登录态、权限、资料加载、全局通知一起接入)。