一、什么是redux?
一个组件里可能会有不少的状态,好比控制某个内容显示的flag,从后端获取的展现数据,那么这些状态能够在本身的单个页面进行管理,也能够选择别的管理方式,redux就是是一种状态管理的方式。npm
二、为何要用redux?
(1) 数据共享,当咱们的不少页面都要用到同一数据时,就能够把数据放到redux中,达到状态共享的目的。
(2) 合并管理状态,业务当中可能会有不少的状态须要维护,且各个状态之间可能还有相互依赖的关系,不统一管理的话很难追踪状态的变化。redux
三、redux的基础概念
(1) store
store是一个仓库,用来存储数据,它能够获取数据,也能够派发数据,还能监听到数据的变化。后端
(2) action
action理解为动做,action的值通常为一个对象,格式如 { type: "", data: "" },type是必需要的,由于reducer处理数据的时候要根据不一样的type来进行不一样的操做。网络
(3) reducer
reducer是初始化以及处理派发的action的纯函数。app
四、如何使用redux?
首先安装redux的依赖,npm i redux -D
(1) 定义action异步
export const countAction = (num) => ({ type: "ADD_NUMBER",data: num })
(2) 定义处理的action的reducer函数
export function counterReducer(prevState = 0, action){ switch(action.type){ case 'ADD_NUMBER': return prevState + num; default return prevState; } }
(3) 建立storefetch
import { createStore } from 'redux' import { counterReducer } from './counterReducer' export const store = createStore(counterReducer)
到这里,store就建立完成了,在组件里能够直接引入store和action,进行派发action的操做,此时有一个Home的组件,咱们要在这里更改state中的数据。spa
import { store } from './store' import { countAction } from './countAction' store.dispatch(countAction(5)) store.getState() // 5
五、redux的三大核心
(1) 单一数据源
当咱们有多个数据须要放到redux中管理时,是放在一个对象里,这个对象放在store中管理,虽然redux并无强制只能建立一个store,可是多个数据源的话不那么容易管理,单一的数据源能够更好的追踪状态的变化。code
(2) state是只读的
想要改变state,没法在组件上直接手动修改state的值,这样能够保证状态不会被随意改变,惟一的方式就是派发action,而是经过集中管理的形式去改变state。
(3) reducer是纯函数
纯函数指的是有相同的输入一定有相同的输出,在这种状况下,不能够修改入参,也不能发送网络请求,也不能进行获取随机数这样的操做,经过reducer将上一个state的状态和当前派发的action链接起来,返回一个新的状态。
六、redux如何进行异步操做?
redux中派发的action默认是只能进行同步的操做的,action被规定为一个对象,那若是想要在redux中进行异步操做,好比发送网络请求该怎么作?
这个时候须要用到中间件,经常使用的中间件有redux-thunk和redux-saga,须要安装依赖 npm i redux-thunk -D/ npm i redux-sage -D
redux-thunk容许派发的action为一个函数,能够在这个函数中进行异步请求,请求执行完成以后再派发一个同步的action,用于修改store中的数据。
redux-saga派发的action仍然为一个对象,可是saga在外侧拦截action,使用生成器函数来监听action,当派发的action中的type为监听的type时,再进行网络请求的发送,以及改变store中的数据。
这里演示一下redux-thunk,在定义store时,须要将中间件传入
import { createStore, applyMiddleware } from 'redux' import { counterReducer } from './counterReducer' import thunk from 'redux-thunk' export const store = createStore(counterReducer,applyMiddleware(thunk))
action就能够写成函数的形式了
import { countAction } from './countAction' export const getInfo = (data) => { return (dispatch) => { // 执行异步操做,异步操做执行完成后,再派发一个同步的action // 这里用fetch作一个演示,发送网络请求后,更改以前的count的值 fetch('/') .then(xhr=>xhr.text()) .then(result=>dispatch(countAction(10))) } }
七、拆分reducer
当reducer须要处理的逻辑比较多时,一个reducer须要进行很是多的switch case的判断,其中有获取异步请求数据的、有全局保存的状态,这时候逻辑就会比较杂乱,此时能够将reducer拆分,而后再进行合并。
假设此时有两个reducer,分别为 countReducer、userInfoReducer,分别的状态保存在store的countInfo和userInfo,此时可使用 combineReducer 这个方法来合并
import countReducer from './countReducer ' import userInfoReducer from './userInfoReducer' import { combineReducers } from 'redux' const reducer = combineReducers({ countInfo: countReducer, userInfo: userInfoReducer }) export default reducer
此时返回的reducer仍然是一个纯函数,combineReducer这个函数就是依次执行传入的reducers,若是store里储存的值发生了变化,就返回新的state,若是没有变化,就返回原来的state。