React 只是 DOM 的一个抽象层,并不是 Web 应用的完整解决方案。有两个方面,它没涉及。
-
代码结构
-
组件之间的通信
2013年 Facebook 提出了 Flux 架构的思想,引发了很多的实现。2015年,Redux 出现,将 Flux 与函数式编程结合一起,很短时间内就成为了最热门的前端架构。
如果你不知道是否需要 Redux,那就是不需要它
多个视图依赖于同一状态。
来自不同视图的行为需要变更同一状态。
只有遇到 React 实在解决不了的问题,你才需要 Redux
简单说,如果你的UI层非常简单,没有很多互动,Redux 就是不必要的,用了反而增加复杂性。
-
用户的使用方式非常简单
-
用户之间没有协作
-
不需要与服务器大量交互,也没有使用 WebSocket
-
视图层(View)只从单一来源获取数据
需要使用Redux的项目:
-
用户的使用方式复杂
-
不同身份的用户有不同的使用方式(比如普通用户和管理员)
-
多个用户之间可以协作
-
与服务器大量交互,或者使用了WebSocket
-
View要从多个来源获取数据
从组件层面考虑,什么样子的需要Redux:
-
某个组件的状态,需要共享
-
某个状态需要在任何地方都可以拿到
-
一个组件需要改变全局状态
-
一个组件需要改变另一个组件的状态
Redux的设计思想:
-
Web 应用是一个状态机,视图与状态是一一对应的。
-
所有的状态,保存在一个对象里面(唯一数据源)。
注意:flux、redux都不是必须和react搭配使用的,因为flux和redux是完整的架构,在学习react的时候,只是将react的组件作为redux中的视图层去使用了。
Redux的使用的三大原则:
-
Single Source of Truth(唯一的数据源)
-
State is read-only(状态是只读的)
-
Changes are made with pure function(数据的改变必须通过纯函数完成)
Redux的流程:
-
store通过reducer创建了初始状态
-
view通过store.getState()获取到了store中保存的state挂载在了自己的状态上
-
用户产生了操作,调用了actions 的方法
-
actions的方法被调用,创建了带有标示性信息的action
-
actions将action通过调用store.dispatch方法发送到了reducer中
-
reducer接收到action并根据标识信息判断之后返回了新的state
-
store的state被reducer更改为新state的时候,store.subscribe方法里的回调函数会执行,此时就可以通知view去重新获取state
Reducer必须是一个纯函数:
Reducer 函数最重要的特征是,它是一个纯函数。也就是说,只要是同样的输入,必定得到同样的输出。Reducer不是只有Redux里才有,之前学的数组方法reduce
, 它的第一个参数就是一个reducer
纯函数是函数式编程的概念,必须遵守以下一些约束。
-
不得改写参数
-
不能调用系统 I/O 的API
-
不能调用Date.now()或者Math.random()等不纯的方法,因为每次会得到不一样的结果
使用react-redux
可以先结合context
来手动连接react和redux。
react-redux提供两个核心的api:
-
Provider: 提供store
-
connect: 用于连接容器组件和展示组件
-
Provider
根据单一store原则 ,一般只会出现在整个应用程序的最顶层。
-
connect
语法格式为
connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)(component)
一般来说只会用到前面两个,它的作用是:
-
把
store.getState()
的状态转化为展示组件的props
-
把
actionCreators
转化为展示组件props
上的方法
-
-
特别强调:
官网上的第二个参数为mapDispatchToProps, 实际上就是actionCreators
只要上层中有Provider
组件并且提供了store
, 那么,子孙级别的任何组件,要想使用store
里的状态,都可以通过connect
方法进行连接。如果只是想连接actionCreators
,可以第一个参数传递为null