3.Redux学习3----redux-saga

redux-saga和redux-thunk功能差不多,都是为了避免直接在组件生命周期函数中做异步操作,便于自动化测试,便于拆分管理。

首先要下包

npm i redux-saga

第零步:在actionCreators中,创建一个action的函数,这个action无需value,只需要一个类型就可

export const getInitList = () => ({
    type:GET_INIT_LIST
})

第一步:todolist.js容器组件中创建一个aciton,派发action

注意此时,因为没有配置saga中间件,若是直接执行,就是直接将aciton派发给store然后是reducer

    componentDidMount(){
        const action = getInitList()
        store.dispatch(action)
    }

只有配置了saga中间件,aciton派发后,saga中间件才会先接受到action,所以接下来第二就是配置saga中间件

第二步:在index.js中引入包,并配置saga中间件

import {applyMiddleware, createStore,compose} from "redux"
import reducer from "./reducer"
import createSagaMiddleware from 'rdux-saga'

const sagaMiddleware = createSagaMiddleware()
// 配置redux开发者工具
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose
// 配置rdux-saga中间件
const enhancer = composeEnhancers(
    applyMiddleware(sagaMiddleware)
);
const store = createStore(
    reducer,
    enhancer
)

export default store

但是配置完了saga中间件,却并没有告诉saga是如何处理传递过来的action的。

第三步:创建sagas.js文件,这个文件就是写saga中间件处理逻辑的回调函数,所以还需在index.js中引入和配置这个处理逻辑的回调函数

import {applyMiddleware, createStore,compose} from "redux"
import reducer from "./reducer"
import createSagaMiddleware from 'redux-saga'
import todoSagas from './sagas'

const sagaMiddleware = createSagaMiddleware()
// 配置redux开发者工具
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose
// 配置rdux-saga中间件
const enhancer = composeEnhancers(
applyMiddleware(sagaMiddleware)
);
// 在store创建时候,配置上
const store = createStore(
reducer,
enhancer
)
// 当有action派送过来时,用todoSagas函数进行处理
sagaMiddleware.run(todoSagas)

export default store

第四步:回到sagas.js文件来,写处理action,做异步操作的逻辑,这里就是异步获取数据,并再创建一个action,将数据存入action通过put派发,给reducer处理

// 注意takeEvery,put的导入目录问题

import {initListAction} from "./actionCreators"
import {GET_INIT_LIST} from "./actionTypes"
import {takeEvery,put} from "redux-saga/effects"
import axios from 'axios'
// generator函数
function* mySaga() {
// 当要处理的action的type是GET_INIT_LIST的时候,调用getInitList函数
yield takeEvery(GET_INIT_LIST, getInitList)
}

// generator函数
function* getInitList() {
// 等待异步操作完成获取数据
const res = yield axios.get('/list.json')
// 再创建一个action
const action = initListAction(res.data)
// put和dispatch功能相同,派发数据给store-》再给reducer处理
yield put(action)
}

export default mySaga;

第五步:reducer接收action,更新state中的list数据返回给store

import {CAHNGE_INPUT_VALUE, ADD_TODOS_ITEM, DELETE_TODOS_ITEM, INIT_LIST} from "./actionTypes"
const defaultState = {
inputValue: "",
list: []
}
//注意reducer只能复制state不能修改,不能直接修改state
export default (state=defaultState,action)=>{
if(action.type === CAHNGE_INPUT_VALUE){
let newState = JSON.parse(JSON.stringify(state))
newState.inputValue = action.value
return newState
}
if(action.type === ADD_TODOS_ITEM){
let newState = JSON.parse(JSON.stringify(state))
newState.list.push(newState.inputValue)
newState.inputValue = ""
return newState
}
if(action.type === DELETE_TODOS_ITEM){
let newState = JSON.parse(JSON.stringify(state))
newState.list.splice(action.index,1)
return newState
}
if(action.type === INIT_LIST){
let newState = JSON.parse(JSON.stringify(state))
newState.list = action.data
return newState
}
return state
}

 

比较下:saga和thunk, saga比较复杂一下,

thunk是将异步请求的代码放在actionCreators.js中管理,仅仅是将action扩展成为函数,没什么api较简单

saga更彻底些,把异步操作放在一个单独的文件中管理,api较多,复杂

saga用于复杂大型项目更便于管理,一般项目用thunk就足够了

你可能感兴趣的:(3.Redux学习3----redux-saga)