示例背景

最常见的 Web 类示例之一: TodoList = Todo list + Add todo button

图解一: React 表示法

r-react

按照 React 官方指导意见, 如果多个 Component 之间要发生交互, 那么 state (即: 数据)就维护在这些 Component 的最小公约父节点上, 也即是<App/>

<TodoList/> <Todo/>以及 <AddTodoBtn> 本身不维持任何 state, 完全由父节点<App/> 传入 props 以决定其展现, 是一个纯函数的存在形式, 即: Pure Component

图解二: Redux 表示法

React 只负责页面渲染, 而不负责页面逻辑, 页面逻辑可以从<App/>中抽取出来, 变成 store

 

r-redux

与图一相比, 几个明显的改进点:

  • 状态及页面逻辑从 <App/>里面抽取出来, 成为独立的 store, 页面逻辑就是 reducer
  • <TodoList/> 及<AddTodoBtn/>都是 Pure Component, 通过 connect 方法可以很方便地给它俩加一层 wrapper 从而建立起与 store 的联系: 可以通过 dispatch 向 store 注入 action, 促使 store 的状态进行变化, 同时又订阅了 store 的状态变化, 一旦状态有变, 被 connect 的组件也随之刷新
  • 使用 dispatch 往 store 发送 action 的这个过程是可以被拦截的, 自然而然地就可以在这里增加各种 Middleware, 实现各种自定义功能, eg: logging

整个流程如同一个中央集权体制:

  • store 就是中央政府, 掌握所有信息
  • 各个 component 只是基层组织, 有事不能自作主张, 只能逐级电话上报, 直到中央政府
  • 中央政府调整状态, 并逐级传达给各级组织, 做出相应的展示

这样一来, 各个部分各司其职, 耦合度更低, 复用度更高, 扩展性更好

图解三: 加入 Saga

 

r-saga

上面说了, 可以使用 Middleware 拦截 action, 这样一来异步的网络操作也就很方便了, 做成一个 Middleware 就行了, 这里使用 redux-saga 这个类库, 举个栗子:

  • 点击创建 Todo 的按钮, 发起一个 type == add 的 action
  • saga 拦截这个 action, 发起 http 请求, 如果请求成功, 则继续向 reducer 发一个 type == addTodoSucc 的 action, 提示创建成功, 反之则发送 type == addTodoFail 的 action 即可

图解四: Dva 表示法

 

r-dva

有了前面的三步铺垫, Dva 的出现也就水到渠成了, 正如 Dva 官网所言, Dva 是基于 React + Redux + Saga 的最佳实践沉淀, 做了 3 件很重要的事情, 大大提升了编码体验:

  • 把 store 及 saga 统一为一个 model 的概念, 写在一个 js 文件里面
  • 增加了一个 Subscriptions, 用于收集其他来源的 action, eg: 键盘操作
  • model 写法很简约, 类似于 DSL 或者 RoR, coding 快得飞起✈️

约定优于配置, 总是好的😆

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注