Redux 是 React的一个状态管理库
为什么要用redux
React有props和state:
- props意味着父级分发下来的属性
- state意味着组件内部可以自行管理的状态,并且整个React没有数据向上回溯的能力,这就是react的单向数据流
这就意味着如果是一个数据状态非常复杂的应用,更多的时候发现React根本无法让两个组件互相交流,使用对方的数据,react的通过层级传递数据的这种方法是非常难受的,这个时候,迫切需要一个机制,把所有的state集中到组件顶部,能够灵活的将所有state各取所需的分发给所有的组件,是的,这就是redux
Redux三大原则
- 1 唯一数据源
整个应用的state都被存储到一个状态树里面,并且这个状态树,只存在于唯一的store中
- 2 保持只读状态
state是只读的,唯一改变state的方法就是触发action,action是一个用于描述以发生时间的普通对象
store.dispatch()是 View 发出 Action 的唯一方法
- 3 数据改变只能通过纯函数来执行
改变state的唯一方法是通过调用store的dispatch方法,触发一个action,这个action被对应的reducer处理,于是state完成更新
Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
import { createStore } from "redux"; // 引入
const reducer = (state = { count: 0 }, action) => {
//----------> ⑴
switch (action.type) {
case "INCREASE":
return { count: state.count + 1 };
case "DECREASE":
return { count: state.count - 1 };
default:
return state;
}
};
const actions = {
//---------->⑵
increase: () => ({ type: "INCREASE" }),
decrease: () => ({ type: "DECREASE" }),
};
const store = createStore(reducer); //---------->⑶
store.subscribe(() => console.log(store.getState()));
store.dispatch(actions.increase()); // {count: 1}
store.dispatch(actions.increase()); // {count: 2}
store.dispatch(actions.increase()); // {count: 3}
react-redux
connect(mapStateToProps, mapDispatchToProps)(MyComponent)
mapStateToProps
这个单词翻译过来就是把state映射到props中去 ,其实也就是把Redux中的数据映射到React中的props中去。
mapDispatchToProps
这个单词翻译过来就是就是把各种dispatch也变成了props让你可以直接使用
redux中间件
redux 的数据流的过程,但在增加了 middleware 后,我们就可以在这途中对 action 进行截获,并进行改变。且由于业务场景的多样性,单纯的修改 dispatch 和 reduce 人显然不能满足大家的需要,因此对 redux middleware 的设计是可以自由组合,自由插拔的插件机制。也正是由于这个机制,我们在使用 middleware 时,我们可以通过串联不同的 middleware 来满足日常的开发,每一个 middleware 都可以处理一个相对独立的业务需求且相互串联:
3.1 redux-thunk
前面我们已经对redux-thunk进行了讨论,它通过多参数的 currying 以实现对函数的惰性求值,从而将同步的 action 转为异步的 action。在理解了redux-thunk后,我们在实现数据请求时,action就可以这么写了:
3.2 redux-promise
不同的中间件都有着自己的适用场景,react-thunk 比较适合于简单的API请求的场景,而 Promise 则更适合于输入输出操作,比较fetch函数返回的结果就是一个Promise对象,下面就让我们来看下最简单的 Promise 对象是怎么实现的:
结合 redux-promise 我们就可以利用 es7 的 async 和 await 语法,来简化异步操作了,比如这样:
3.3 redux-saga
redux-saga是一个管理redux应用异步操作的中间件,用于代替 redux-thunk 的。它通过创建 Sagas 将所有异步操作逻辑存放在一个地方进行集中处理,以此将react中的同步操作与异步操作区分开来,以便于后期的管理与维护。对于Saga,我们可简单定义如下:
Saga = Worker + Watcher
redux-saga相当于在Redux原有数据流中多了一层,通过对Action进行监听,从而捕获到监听的Action,然后可以派生一个新的任务对state进行维护(这个看项目本身的需求),通过更改的state驱动View的变更。