1. 本文写在去年8月,有着我对redux最佳实践的思考和总结。
王国维的《人间词话》的三重境
古今之成大事业、大学问者,必经过三种之境界。
- “昨夜西风凋碧树,独上高楼,望尽天涯路”,此第一境也;
- “衣带渐宽终不悔,为伊消得人憔悴”,此第二境也;
- “众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”,此第三境也。
大纲
- redux 基础知识和 react-redux
- redux 周边生态探索
- 有哪些功能?(粗略介绍)
- 有哪些很不错的第三方库?(详细介绍)
- 最佳实践介绍(dva)
一: redux 基础知识和 react-redux
- 三个基本原则
- 数据流
- 在 React 应用中使用 Redux(react-redux)
redux 三个基本原则
- 整个应用只有唯一一个 Store 实例
- State 只能通过触发 Action 来更改
- State 的更改 必须写成纯函数(Reducer),(oldState, action) => newState,也就是每次更改总是返回一个新的 State
redux 两个显著的特点
- 可预测性(Reducer 是纯函数)。
- 扩展性强(middleware)。
单向数据流
- Actions 是 store.dispatch(action),它是每次数据改变的源头。
- 如果有 middleware 将先进入 middleware
- Reducer 管理 state, 也就是 (oldState, action) => newState 的集合。
- 当 state 改变后, View Provide 就会更改视图
连接 React (react-redux)
- 使用 Provider 在根组件 注入 Store
- 容器组件使用 connect() 方法连接 Redux
1. 使用 Provider 在根组件 注入 Store
2. 容器组件使用 connect() 方法连接 Redux
那么我们如何获取容器组件的依赖呢?
容器组件及其子组件需要的两个能力:
- 读数据:获取 redux 的 state
- 改数据:向 redux dispatch actions
使用步骤1
- mapStateToProps:从 store 的 state 里把容器组件依赖的部分 state 取出来,成为组件的 props。
- mapDispatchToProps: 将特定的 dispatch 函数取出来变为 props 。
注: bindActionCreators 将 ActionCreator 和 store 的 dispatch 绑定到一起,返回一个特定的 dispatch 函数,组件调用即可触发 store.dispatch(action)
使用步骤2
在 render 等函数里面 取出相应 props,自己使用或者传给子组件
分离容器组件和展示组件
redux 的重要思想:分离容器组件和展示组件。
容器组件
在应用中,只有 最顶层组件是对 Redux 可知。
展示组件
应该是“笨拙”的,是通过父组件传递的 props 来获取数据和更改数据的 dispatch,它是感知不到 redux 存在的,具有很强的复用性。
如何分辨容器组件和展示组件的思考
1. 状态
- 容器组件维护多个状态
- 展示组件维护极少的状态(一般是 ui 状态)
2. ui
- 容器组件无关 ui,几乎没有 css 样式、html 标签,通过组合展示组件来构造容器组件
- 展示组件 ui 强相关,大量 css 和 html 标签
容器组件示例(ArticleBox 组件):
展示组件示例(Article 组件):
容器组件和展示组件对比
二: 探索阶段
- 探索 redux 生态
- 有哪些功能?(粗略介绍)
- 有哪些很不错的第三方库?(详细介绍)
- 最佳实践介绍(dva)
redux 生态
- 连接到其他库
- 开发(debug)工具
- 各类实用工具
- 简化 api
- 计算、处理数据
- 异步 action
连接到其他库
- react-redux
- react-router-redux
- redux-immutablejs
实用工具
- redux-thunk — 用最简单的方式书写异步 action creator
- redux-actions — 在初始化 reducer 和 action 构造器时减少样板代码
- Reselect Data => View store 的 select 方案,用于提取数据的筛选逻辑。
- 等等
开发测试工具
devtool
redux-devtools — 一个使用时间旅行 UI 、热加载和 reducer 错误处理器的 action 日志工具
DevTools accepts monitor components(Custom Monitors)
Redux Logger
- redux-logger — 记录所有 Redux action 和下一次 state 的日志
不错的第三方库
我这里就介绍一个第三方库
- redux-action
简化 redux api
redux-actions — 在初始化 reducer 和 action 构造器时减少样板代码
createAction
下图这是 createAction 的效果 (我把我博客的 actions refactor 一下,上面是简化后。)

内部实现
原理就是高阶函数, createAction 返回一个函数,
三: 最佳实践
dva 介绍
google dva...第一个结果
dva 框架
实际上 dva 是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装,没有引入任何新概念,全部代码不到 100 行。
由支付宝前端团队开发。
他们总结的 React + Redux 最佳实践
dva 的由来
dva 特点
api 风格方面非常像 vue,并且沿袭了 vue 的简单易上手、api 简洁的特点。
dva 使用
关于 dva 的思考
react redux
react redux 的思想从一开始就是 开放的,海纳百川,官方给出的最佳实践是 组合式 的,根据需求、喜好的不同,会有十几种最佳实践。。。。
- 优点:社区异常活跃;扩展性强、非常灵活;中台组件库基于 React。
- 缺点:学习成本高,新手上手慢;太灵活,周边生态百花齐放,如果没有一定的约束,非常不易于团队合作。
vue
去年开始 vue 以上手容易、api 简洁优雅出名,对于同类需求,官方给出的最佳实践几乎是唯一的。
- 优点:学习成本低,易上手;最佳实践统一,利于团队合作;作者非常给力,在 vue2.0 里,发布了很多特别棒的新 feature(jsx,virtual dom,服务器流式渲染); weex 扩展了 vue 在移动端的能力。
- 缺点:社区活跃低于 React;扩展性、灵活性差。
dva
dva 结合了 react 和 vue 两者的优点
- 学习成本低,易上手
- 最佳实践统一,利于团队合作
- 社区异常活跃,扩展性强
- 中台 dpl 基于 React
缺点:
- 降低了 redux 的扩展性、灵活性
对 dva 的态度
- 学习借鉴
- 学习思想,借鉴他们的最佳实践; 持续跟进
- 使用? or 自己造轮子?
- 使用: 当其比较成熟时,对于复杂页面(尤其是单页应用)可以考虑使用。
- or 自己造轮子: 借鉴学习其的特点和功能自己造轮子