iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 27
0

還記得之前介紹過 redux 的基本用法嗎?
因為覺得 React 基礎講的差不多了,今天決定回過頭來講講 redux middleware。

Redux-middleware

如果要用簡單的一句話解釋 redux-middleware 我會這樣說:

action 被 dispatch 之後傳到 reducer 以前會經過的地方

如果寫過 nodejs express 的朋友可能會很熟悉,這就跟 request 與 response 之間的 middleware 一樣意思嘛!

為什麼需要 redux-middleware?
redux-middleware 用來處理如非同步行為、一次派發多個 action 等行為,其實他並不是特別用來做特定行為,但它讓你對action 到 reducer 的掌控度更高,能夠執行更多的操作。

這邊以我自己寫的 side-project 為範例,實作登入填寫帳號密碼欄位後,call backend api 拿到 token 的過程。

首先要先下載它

npm i redux-thunk
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import authReducer from '../reducers/authReducer';


export default () => {
    const store  = createStore(
        authReducer,
        applyMiddleware(thunk)
    )

    return store;
}

利用 redux 的 applyMiddleware 函式把 thunk 包起來

以往 dispatch 的 action 是一個物件,裡面有 type 與要帶上的 data,thunk 讓我們可以 dispatch 一個 function 出去,該 function 讓我們可以做一些額外的工作,做完之後才再次 dispatch 給 reducer 接收的 action。

action:

export const authLogin = (username, password) => {
    return dispatch => {
        dispatch(authStart());
        axios.post('http://127.0.0.1:8000/auth/token/login',{
            username,
            password
          }
    )
        .then(res => {
            const token = res.data.auth_token;
            localStorage.setItem('token',token);
            dispatch(authSuccess(token));
            history.push('/computerlist');
        })
        .catch(err => {
            dispatch(authFail(err));
            history.push('/');
        })
    }
}

reducer:

const reducer = (state = initialState, action) => {
    switch(action.type) {
        case 'AUTH_START':
            return {
                ...state,
                error: null,
                loading: true
            };
        case 'AUTH_SUCCESS':
            return {
                ...state,
                token: action.token,
                error: null,
                loading: false
            };
        case 'AUTH_FAIL':
            return {
                ...state,
                error: action.error,
                loading: false
            };
        case 'AUTH_LOGOUT':
            return {
                ...state,
                token: null
            }
        default: 
            return state
    }
   
}

登入 form:

const handleSubmit = (e) => {
    e.preventDefault();
    dispatch(authLogin(props.values.username,props.values.password));
}

form submit 時 dispatch 的是 authLogin function,而這個 authLogin 回傳的並不是物件而是一個 function ,裡面針對 call api 的階段進行 dispatch ,reducer 中並沒有 authLogin 這個 type ,而是接收 authLogin 派發的 action。

透過 thunk 處理非同步事件也確保某些 action 在被 dispatch 時是帶上正確的資料的(上例就是避免 token 還沒回傳就派發,而我們也可以在 thunk 中做錯誤處理機制,對 action 的控制的確提升了。)

以上就是 redux-thunk 的基本應用,比較進階的 middleware 還有 redux-saga,可以做到比 thunk 更多的事情,當然 middleware 也可以自己設計,就交給各位自行研究啦!


上一篇
【Day 26】誰說一定要用別人寫好的 hooks - Custom Hooks
下一篇
【Day 28】React 的好搭檔 - Material UI && Recharts
系列文
React.js 從 【0】 到【1】推坑計畫 30

尚未有邦友留言

立即登入留言