redux-thunk
和redux-saga
都是redux的中間件,都是用來處理異步請求的。中間件是指在action
與store
之間實現某種功能的函數
redux-thunk的用法
一般redux中action默認值返回對象,不能返回函數(會報錯)。redux-thunk
正好解決了這個問題,它使得action可以返回函數,一般我們就把異步請求寫在函數裏。
store/index.js
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'
const enhancer = composeEnhancers(
applyMiddleware(thunk),
)
const store = createStore(
reducer,
enhancer
)
export default store
組件TodoList.js
import { getInitDataAction } from './store/actionCreator'
import store from './store'
componentDidMount() {
const action = getInitDataAction() // getInitDataAction返回一個函數,返回時會執行這個函數
store.dispatch(action)
}
actionCreator.js
import { INIT_TODO_LIST } from './actionTypes'
import axios from 'axios'
export getInitTodoListAction (data) => ({
type: INIT_TODO_LIST,
data
})
export getInitDataAction = () => {
return (dispatch) => {
axios.get('/list.json').then(res => {
const data = res.data
const action = getIninTodoListAction(data)
dispatch(action)
})
}
}
redux-saga的用法
redux-saga
中間件會把所有異步請求放到一個文件,集中管理,原理是,組件dispatch
某個action
時,會被redux-saga
捕獲,再執行相應的函數,函數中執行異步請求。
store/index.js
import { createStore, applyMiddleware, compose } from 'redux'
import reducer from './reducer'
import createSagaMiddleware from 'redux-saga'
import mySaga from './sagas.js'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const sagaMiddleware = createSagaMiddleware()
const enhancer = composeEnhancers(
applyMiddleware(sagaMiddleware)
)
const store = createStore(
reducer,
enhancer
)
sagaMiddleware.run(mySaga)
export default store
sagas.js
import { put, takeEvery } from 'redux-saga/effects'
import { GET_INIT_DATA } from './actionTypes'
import { getInitTodoListAction } from './actionCreator'
import axios from 'axios'
function* getInitList() {
try {
const res = yield axios.get('/list.json')
const action = getInitTodoListAction(res.data)
yield put(action)
} catch(e) {
console.log('list.json 連接網絡失敗')
}
}
function* mySaga() {
yield takeEvery(GET_INIT_TADA, getInitList) //當GET_INIT_TODO_LIST的action被dispatch時執行getInitList函數
}
export default mySaga
store/actionCreator.js
import { INIT_TODO_LIST, GET_INIT_DATA } from './actionTypes'
import axios from 'axios'
export getInitTodoListAction (data) => ({
type: INIT_TODO_LIST,
data
})
export getInitDataAction () => ({
type: GET_INIT_DATA
})
組件TodoList.js
import { getInitDataAction } from './store/actionTypes'
import store from './store'
componentDidMount() {
const action = getInitDataAction()
store.dispatch(action) // redux-saga會捕獲到action.type=GET_INIT_DATA的動作,再執行sagas.js中的getInitList函數,執行異步請求
}