一、概述
Flux和Redux 是React生态中重要的组成部分,个人觉得,它们核心功能就是将页面 和 数据+逻辑 解耦,将数据+逻辑 进一步抽象组件化。
二、Flux
Flux是一套架构模式,而不是代码框架。所谓的架构模式,是一套方法论,指导系统如何更好搭建。例如模块如何划分?模块间如何通信?Web开发中的MVC模式,其实就是架构模式。
1、四大核心部分
- dispatcher:负责两件事,一是分发和处理Action,二是维护Store。
- Store:数据和逻辑部分。
- views:页面-React 组件,从 Store 获取状态(数据),绑定事件处理。
- actions:交互封装为action,提交给Store处理。
2、架构设计
- 【单向数据流】:
Action -> Dispatcher -> Store -> View
- 页面交互数据流,如用户点击按钮:
View -> Create Action -> Dispatcher(由此进入【单向数据流】)
Flux参考
具体的Demo和用法参考一下教程,很详细了~
ReacFlux教程
三、Redux
1、什么Redux?
Redux 是 JavaScript 状态容器, 提供可预测化的状态管理。那什么是可以预测化,我的理解就是根据一个固定的输入,必然会得到一个固定的结果。
Redux是进化Flux,它是在Flux架构模式指导下生成的代码框架,也进一步进行架构约束设计。
- Redux 的适用场景:多交互、多数据源。
2、Redux的核心思想
借用阮一峰大神的话:Redux 的设计思想很简单,就两句话。
- 1、Web 应用是一个状态机,视图与状态是一一对应的。
- 2、所有的状态,保存在一个对象里面。
3、Redux的架构约束
对于 Store 的约束
一个应用对应一个全局Store,可用单例模式来实现。
Store只有store.getState()
、store.dispatch()
、store.subscribe()
三个方法。
初始化需要绑定reducer函数
,调用store.dispatch方法
会自动触发reducer函数
的执行。对于 State 的约束
一个 State 对应一个应用,整个应用只有一个 State 对象,包含所有数据。整个应用只维护成一个树形state。
State对象是只读的,最好把 State对象设成只读,不可变,即声明为
const`。state的只能通过action触发生成新的state。
如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。对于 Actions 的约束
Redux简化了Action,它就是一个单纯的包含{ type, payload, error, meta }
的对象;type
是一个常量用来标示动作类型;payload
是这个动作携带的数据。其中的type
属性是必须的,表示 Action 的名称,其他属性可以自由设置,社区有一个规范可以参考。不允许扩展其他自定义属性字段。
-
引入 Reducer :作用是保证State不可变,处理State数据。
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。因此,
reducer函数
必须是一个纯函数。也就是说,只要是同样的输入,必定得到同样的输出。
也就是说,一个reducer函数
会接受初始状态originalState
和action
两个参数,返回一个新的state:(originalState, action) => newState
。
4、Redux的工作流
- 单向数据流:
store.dispatch(action) -> reducer(state, action) -> store.getState()
5、Redux的简单Demo
- 实现Reducer
// state只读
const defaultState = 0;
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'ADD':
return state + action.payload;
default:
return state;
}
};
- 初始化Store,需要绑定reducer函数
import { createStore } from 'redux';
var store = createStore(reducer)
- 获取状态State
store.getState()
- 监听状态State
// 注册
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
// 销毁
unsubscribe();
- 分发Actions
const action = {
type: 'ADD',
payload: 'Learn Redux'
};
store.dispatch(action);
5、Redux让开发者专注于数据流的处理。
Redux框架约束Store
,封装了 订阅store.subscribe
和 分发store.dispatch
的行为;封装了Action
的动作;抽象定义了State
对象。框架定义一整套完整的工作流程,开发者只需要关注于React组件页面,专注于相关业务数据流的设计和处理。
框架提供以下方式支持数据多样性。
通过Actions实现数据多样性:通过action的属性字段(
payload、errer、meta
)传递用户自定义数据。通过State实现数据多样性:state对象只读,但是可以有多个的属性。
const initialState={
a: data 1,
b: data 2,
c: data 3
}
我们可以把 Reducer 函数拆分,不同的函数负责处理不同属性,最终把它们合并成一个大的 Reducer 即可。Redux 提供了一个 combineReducers
方法,用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,将它们合成一个大的 Reducer。
const reducer = combineReducers({
a: doSomethingWithA,
b: processB,
c: c
})
// 等同于
function reducer(state = {}, action) {
return {
a: doSomethingWithA(state.a, action),
b: processB(state.b, action),
c: c(state.c, action)
}
}
四、中间件技术,让Redux支持异步
Redux从生成action,dispatch action,生成新的state,页面更新,这一工作流是同步的。
实际开发中,需要异步的场景,redux如何支持呢? 这需要用到中间件技术。
什么是中间件?
通俗理解,就是额外增加一层中间层,这一层单独处理一组通用的逻辑行为,例如打日志、异步操作等。-
Redux原生方法
applyMiddlewares()
它是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。源码实现原理是将入参的所有中间件被放进了一个数组chain
,然后嵌套执行,最后执行store.dispatch
。
异步中间件
redux-thunk
、redux-promise
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducers';
// Note: this API requires redux@>=3.1.0
const store = createStore(
reducer,
applyMiddleware(thunk)
);
Redux参考
阮一峰:Redux 入门教程(一):基本用法
阮一峰:Redux 入门教程(二):中间件与异步操作
Redux入门教程(快速上手)
Redux教程