天天看點

redux中間件之redux-thunkRedux-thunk

最近在初學redux,也接着學了redux裡的中間件。

對于redux,本來 store.dispatch 隻能派發的是一個對象給store。

加了 redux 中間件後:其實是對 store.dispatch 方法做了更新;更新後可接收對象,也可接收函數,使得可處理異步代碼了

如果派發的的是對象,則中間件會直接傳給store;如果派發的是函數的話,則會先執行這個函數
redux中間件之redux-thunkRedux-thunk

注意:這裡的中間件指的是 store 和 action 的中間

常見的 redux 中間件 :redux-thunk 和 redux-saga 都是處理異步的

前者是通過把異步代碼放在action裡,後者是把異步代碼單獨放在一個檔案裡

先将 redux-thunk 中間件

Redux-thunk

Redux-thunk思想: 異步請求放到action裡

安裝:

npm install redux-thunk

引入:

在建立store的地方引入這個中間件

即在store目錄下的 index.js 引入react 的 applyMiddleware 和 redux-thunk,

然後在用

createStore ()

方法中,設第二個參數:通過

applyMiddleware ()

方法使用 redux-thunk 這個中間件

//栗子
import {createStore, applyMiddleware} from 'redux'
import reducer from './reducer.js'
import thunk from 'redux-thunk'

export default createStore(
    reducer,
    applyMiddleware(thunk)
    );
           

注:Chrome插件也是屬于中間件, 如果也想擴充 redux-devtools (也原本是放createStore第二個參數) 因為多使用了一些中間件,比如 redux-thunk 後,則createStore()的第二個參數的 applyMiddleware() 不能是redux-devtools 擴充Chrome插件的那些代碼了

若既想要使用 redux-devtools 這個 Chrome 擴充插件,又想使用中間件的話

怎麼辦:GitHub 的 redux-devtools-extension 提供了解決方法

https://github.com/zalmoxisus/redux-devtools-extension

import {createStore, applyMiddleware, compose} from 'redux'
import reducer from './reducer.js'
import thunk from 'redux-thunk'

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;

const enhancer = composeEnhancers(
   applyMiddleware(thunk)
);
const store = createStore(reducer, enhancer);
export default store

           

使用: 在action中使用redux-thunk

本來 action/ actionCreateor.js 應該傳回的是對象,使用了redux-thunk 後則也可return 傳回一個函數了,在這個函數裡去寫異步代碼(如ajax請求)

由于 action 此時是函數了,是以 react 會去執行這個函數;

在這個函數裡如果想把資料更新到 store 上的話,又是同樣的 store.dispatch (一個action),不過由于此時這個return 傳回的函數接收到的參數就是store.dispatch方法,則可直接dispatch(action對象)

// 栗子
// 元件裡
componentDidMount(){
    const action = getTodolist();
    store.dispatch(action)
}
 
 
 
// actionCreateor.js檔案
export const initListAction =(data)=>({
    type: INIE_TODOLIST,
    value: data
})
 
export const getTodolist =()=>{
    return (dispatch)=>{
            axios.get('./list.json').then((res)=> {
                const data = res.data;
                const action = initListAction(data);
                dispatch(action)
            })
        }
    }
 
 
// reducer.js 檔案裡
export const initListAction =(data)=>({
    type: INIE_TODOLIST,
    value: data
})
 
           

我的總結思路:

store.dispatch

一個函數,這個函數傳回的也是函數A,

在這個傳回的函數A裡寫的是異步的代碼,和進一步的真正的action事件的派發(第二次store.dispatch(),且派發的這個對象的資料就是來自異步後的資料)