React
React是声明式,高效且灵活的用于构建用户界面的JS库。React可以将一些简短的,独立的代码(组件)组合成复杂的UI界面。
React特点
声明式
想要实现什么目的,不具体说怎么做。
简洁易懂,利于工程化/模块化维护。
不使用变量,避免了创建/修改状态的繁琐。
函数式编程是声明式的一种类型,声明式强调目标而不是具体过程。
组件化
编写便捷
细节
构造函数
使用构造函数的原因:创建组件两种方法,一种是 class类来创建,一种是构造函数创建组件。
生命周期函数(un)mount
Dom元素构造的同时需要进行渲染组件,有些方法需要设置生命周期,否则会占用内存资源。在这个方法作用完成后卸载他,留出进程资源。
JSX
const element = <h1>Hello, world!</h1>;
使用JSX的原因。React 认为渲染逻辑本质上与其他 UI 逻辑内在耦合,比如,在 UI 中需要绑定处理事件、在某些时刻状态发生变化时需要通知到 UI,以及需要在 UI 中展示准备好的数据。React 并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为“组件”的松散耦合单元之中,来实现关注点分离。
React [不强制要求](https://zh-hans.reactjs.org/docs/react-without-jsx.html)使用 JSX,但是大多数人发现,在 JavaScript 代码中将 JSX 和 UI 放在一起时,会在视觉上 有辅助作用。它还可以使 React 显示更多有用的错误和警告消
图解法、架构
图解一: React 表示法

按照 React 官方指导意见, 如果多个 Component 之间要发生交互, 那么状态(即: 数据)就维护在这些 Component 的最小公约父节点上, 也即是<App/>
<TodoList/> <Todo/> 以及<AddTodoBtn/> 本身不维持任何 state, 完全由父节点<App/> 传入 props 以决定其展现, 是一个纯函数的存在形式, 即: Pure Component
图解二: Redux 表示法
React 只负责页面渲染, 而不负责页面逻辑, 页面逻辑可以从中单独抽取出来, 变成 store
与图一相比, 几个明显的改进点:
- 状态及页面逻辑从
<App/>里面抽取出来, 成为独立的 store, 页面逻辑就是 reducer <TodoList/>及<AddTodoBtn/>都是 Pure Component, 通过 connect 方法可以很方便地给它俩加一层 wrapper 从而建立起与 store 的联系: 可以通过 dispatch 向 store 注入 action, 促使 store 的状态进行变化, 同时又订阅了 store 的状态变化, 一旦状态有变, 被 connect 的组件也随之刷新- 使用 dispatch 往 store 发送 action 的这个过程是可以被拦截的, 自然而然地就可以在这里增加各种 Middleware, 实现各种自定义功能, eg: logging
这样一来, 各个部分各司其职, 耦合度更低, 复用度更高, 扩展性更好
图解三: 加入 Saga

上面说了, 可以使用 Middleware 拦截 action, 这样一来异步的网络操作也就很方便了, 做成一个 Middleware 就行了, 这里使用 redux-saga 这个类库, 举个栗子:
- 点击创建 Todo 的按钮, 发起一个 type == addTodo 的 action
- saga 拦截这个 action, 发起 http 请求, 如果请求成功, 则继续向 reducer 发一个 type == addTodoSucc 的 action, 提示创建成功, 反之则发送 type == addTodoFail 的 action 即可
图解四: Dva 表示法

有了前面的三步铺垫, Dva 的出现也就水到渠成了, 正如 Dva 官网所言, Dva 是基于 React + Redux + Saga 的最佳实践沉淀, 做了 3 件很重要的事情, 大大提升了编码体验:
- 把 store 及 saga 统一为一个
model的概念, 写在一个 js 文件里面 - 增加了一个 Subscriptions, 用于收集其他来源的 action, eg: 键盘操作
- model 写法很简约, 类似于 DSL 或者 RoR, coding 快得飞起✈️
未解决的问题
- 通信:组件之间如何通信?
- 数据流:数据如何和视图串联起来?路由和数据如何绑定?如何编写异步逻辑?
