工作中常用的的中间件
redux-thunk
这个就是就是我们实现的thunk中间件,使用方式是一样的
- 下载中间件
npm install redux-thunk
- 引入中间件、并注册中间件
import thunk from 'redux-thunk'
import { applyMiddleware } from 'redux'
export const store = createStore(RootReducer, applyMiddleware(thunk))
现在就可以愉快的使用了
redux-saga
用redux-saga来实现计数器延期功能
与redux-thunk功能一致,但比redux-thunk跟强大,redux-saga可以将异步操作从Action Creator 文件抽离出来,放在一个单独的文件中,这样我们项目代码更加可维护了
takeEvery: 用来接收action,第一个参数时要接收的action类型字符串,第二个参数是执行的异步方法
put: 用来触发一个action 与dispatch 方法一致
要求我们默认导出一个generator函数
- 下载 redux-saga
npm install redux-saga
- 创建 redux-saga 中间件
import createSagaMiddleware form 'redux-saga'
const sagaMiddleware = createSagaMiddleware()
createStore(RootReducer, applyMiddleware(sagaMiddleware))
- 创建异步操作action
export const increment_async = () => ({type: INCREMENT_ASYNC})
- 使用saga 拦截异步操作的action,等待异步操作完成之后执行同步更改的action
import { takeEvery, put, delay } from 'redux-saga/effects'
import { increment } from '../actions/counter.actions'
import { INCREMENT_ASYNC } from '../const/counter.const'
function* increment_async_fn () {
yield delay(2000)
yield put(increment(10))
}
export default function* counterSage () {
yield takeEvery(INCREMENT_ASYNC, increment_async_fn)
}
- 启动saga
import createSagaMiddleware from 'redux-saga'
import counterSage from './sagas/counter.sagas'
const sagaMiddleware = createSagaMiddleware()
export const store = createStore(RootReducer, applyMiddleware(sagaMiddleware))
// 执行这个方法必须要在createStore之后
sagaMiddleware.run(counterSage)
redux-saga中的action传参
- 视图中传入参数
- 在action中接受参数并添加到action中
export const increment_async = payload => ({type: INCREMENT_ASYNC, payload})
- 在saga中间件中接收参数并传递给执行更改操作的action
function* increment_async_fn (action) {
console.log(action)
yield delay(2000)
yield put(increment(action.payload))
}
saga文件的拆分与合并
使用saga来延迟显示和隐藏弹出框案例
- 创建异步action,并把action.type定义为常量
export const show_async = () => ({type: SHOWMODAL_ASYNC})
// 定义常量
export const SHOWMODAL_ASYNC = 'showModal_async'
- 在saga中拦截异步aciton,执行异步操作后触发同步更改action
import { takeEvery, put, delay } from 'redux-saga/effects'
import { show } from '../actions/modal.actions'
import { SHOWMODAL_ASYNC } from '../const/modal.const'
function* showModal_async_fn (){
yield delay(2000)
yield put(show())
}
export default function* counterSage () {
yield takeEvery(SHOWMODAL_ASYNC, showModal_async_fn)
}
- 视图中去触发异步action
// function Modal ({ show_async }) {}
我们发现这个saga文件中即接收了弹出框的异步action 又接收了计数器异步action,这样过多的异步操作之后代码变得臃肿无法维护,所以我们需要去拆分合并saga
合并saga
我们合并saga需要用到all方法,all方法接收一个数组参数,这个数组的成员即是我们分离的saga的调用
- 创建src/store/sagas/modal.sagas.js 文件,把弹出框的代码抽离到当前这个文件
import { takeEvery, put, delay } from 'redux-saga/effects'
import { show } from '../actions/modal.actions'
import { SHOWMODAL_ASYNC } from '../const/modal.const'
function* showModal_async_fn (){
yield delay(2000)
yield put(show())
}
export default function* modalSaga (){
yield takeEvery(SHOWMODAL_ASYNC, showModal_async_fn)
}
- 创建src/store/sagas/root.saga.js文件,导入创建的saga文件合并一起
import { all } from 'redux-saga/effects'
import counterSaga from './counter.sagas'
import modalSaga from './modal.sagas'
export default function* rootSaga() {
yield all([
counterSaga(),
modalSaga()
])
}
- 更改运行saga传入为rootsaga
import rootSaga from './sagas/root.saga'
const sagaMiddleware = createSagaMiddleware()
export const store = createStore(RootReducer, applyMiddleware(sagaMiddleware))
// 执行这个方法必须要在createStore之后
sagaMiddleware.run(rootSaga)
### redux-actions中间件
Redux-actions帮助我们简化了action代码和reducer代码、
redux流程中大量的样板代码读写狠痛苦,使用redux-actions可以简化aciton和reducer的处理
下载redux-actions
npm install redux-actions
创建action
createAction接收一个字符串作为参数,这个字符串就是action对象里面的type值, 返回值就是自己定义的
actionCreate 函数,触发和接收action的时候我们只需要使用createAction的返回值就可以了,就不需要把type值设置为常量了
import { createAction } from 'redux-actions'
const increment_action = createAction('increment')
const decrement_action = createAction('decrement')
创建reducer
createReducer 接收两个参数,第一个参数是一个对象,对象的key就是用createAction 创建的 action,对象的value就是执行action的操作
第二个参数就是初始值
import { handleActions as createReducer } from 'redux-actions'
import { increment_action, decrement_action} from '../actions/counter.action'
const initialState = {count: 0}
const counterReducer = createReducer({
[increment_action]: (state, action) => ({count: state.count + 1}),
[decrement_action]: (state, action) => ({count: state.count + 1})
}, initialState)
export default counterReducer
用redux-actions 来实现计数器案例
- 用redux-actions创建action
import { createAction } from 'redux-actions'
export const increment = createAction('increment')
export const decrement = createAction('decrement')
- 用redux-actions创建reducer
import { increment, decrement } from './../actions/counter.actions'
import { handleActions as createReducer } from 'redux-actions'
const initialState = {
count: 0
}
const handIncrement = (state, action) =>({count: state.count + 1})
const handDecrement = (state, action) =>({count: state.count - 1})
export default createReducer({
[increment]: handIncrement,
[decrement]: handDecrement
}, initialState)
- 传递参数在视图中传递,直接在reducer中接收
// 视图
function Count({count,increment,decrement}) {
return
{count}
}
// reducer 中
const handIncrement = (state, action) =>({count: state.count + action.payload})
const handDecrement = (state, action) =>({count: state.count - action.payload})
原文地址: https://kspf.xyz/archives/22/