成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Redux入門0x105: redux 中間件

brianway / 808人閱讀

摘要:概述前一章講了的,這一章講中很神奇的中間件。我們也可以使用中間件來擴展的功能。當然一樣的,這樣的中間件也已經(jīng)存在了,日志的中間件也已經(jīng)存在了查看效果資源源碼

0x000 概述

前一章講了reduxAction Creator,這一章講redux中很神奇的中間件。

0x001 手寫中間件

在項目中,我們經(jīng)常會有記錄一些事件或者在某些事件發(fā)生的時候做某些事的需求,比如api接口鑒權操作、日志記錄操作等,一般我們都可以用中間件來完成,中間件具有可拔插、可擴展的特點。我們也可以使用中間件來擴展redux的功能。

記錄每一次的actionstate變化
我們在之前是這么使用redux的:

import {createStore} from "redux"

function counter(state = 0, action) {
    switch (action.type) {
        case "INCREMENT":
            return state + 1
        default:
            return state
    }
}

let store = createStore(counter)

store.subscribe(() => {
    // console.log(store.getState())
})

const ACTION_INCREMENT = "INCREMENT"

const increment = () => {
    return {
        type: ACTION_INCREMENT
    }
}
const action = increment()
store.dispatch(action)
store.dispatch(action)
store.dispatch(action)

通過store.dispatch完成對數(shù)據(jù)的修改,現(xiàn)在我們希望記錄每一次對數(shù)據(jù)的修改,我們可以這么做

console.log("action", action.type)
store.dispatch(action)
console.log("next state", store.getState())

console.log("action", action.type)
store.dispatch(action)
console.log("next state", store.getState())

console.log("action", action.type)
store.dispatch(action)
console.log("next state", store.getState())

效果很明顯,豬才會這么做

封裝1:封裝成函數(shù),可以,經(jīng)常我們也是這么做的,但是不好

const dispatch = (store, action) => {
    console.log("action", action.type)
    store.dispatch(action)
    console.log("next state", store.getState())
}

dispatch(store, action)

封裝2:hackstore.dispatch,沒毛病,但是不夠優(yōu)雅并且如果希望有多個中間件不太好辦,并且希望中間鍵可以串聯(lián)起來

const storeDispatch=store.dispatch
store.dispatch= (action) => {
    console.log("action", action.type)
    storeDispatch(action)
    console.log("next state", store.getState())
}
store.dispatch(action)

封裝3:多個中間件串聯(lián)

這里寫了兩個中間鍵,一個是前中間件,一個是后中間件,在執(zhí)行 before(store)的時候,其實我們已經(jīng)將store.dispatch替換成了beforedispatch,所以我們在afterdispatch第二次替換的時候,const storeDispatch = store.dispatch中的 store.dispatch其實是before.dispatch,所以,當我們執(zhí)行store.dispatch(increment())的時候,調用鏈其實是:store#dispatch=after#dispatch -> before#dispatch -> before#console.log -> store#dispatch -> after#console.log
const before = (store) => {
    const storeDispatch = store.dispatch
    const dispatch=(action) => {
        console.log("before", action.type,store.getState())
        storeDispatch(action)
    }
    store.dispatch = dispatch
}

const after = (store) => {
    const storeDispatch = store.dispatch
    const dispatch = (action) => {
        storeDispatch(action)
        console.log("after",action.type,store.getState())
    }
    store.dispatch=dispatch
}
before(store)
after(store)
store.dispatch(increment())

查看輸出:

封裝4:隱藏hack,減少樣板代碼

const before = (store) => {
    const storeDispatch = store.dispatch
    return (action) => {
        console.log("before", action.type, store.getState())
        storeDispatch(action)
    }
}

const after = (store) => {
    const storeDispatch = store.dispatch
    return (action) => {
        storeDispatch(action)
        console.log("after", action.type, store.getState())
    }
}

const applyMiddleware = (store, ...middlewares) => {
    middlewares.reverse()
    middlewares.forEach(middleware => {
        store.dispatch = middleware(store)
    })
}

applyMiddleware(store, before, after)

store.dispatch(increment())

封裝5:不使用 hack

const before = (store) => {
    return (storeDispatch) => {
        return (action) => {
            console.log("before", action.type, store.getState())
            storeDispatch(action)
        }
    }
}
const after = (store) => {
    return (storeDispatch) => {
        return (action) => {
            storeDispatch(action)
            console.log("after", action.type, store.getState())
        }
    }
}

const applyMiddleware = (store, ...middlewares) => {
    middlewares.reverse()
    let storeDispatch = store.dispatch
    middlewares.forEach(middleware => {
        storeDispatch = middleware(store)(storeDispatch)
    })
    // store.dispatch = storeDispatch
    return {...store, ...{dispatch: storeDispatch}}
}

store = applyMiddleware(store, before, after)

store.dispatch(increment())

封裝6:優(yōu)化中間件寫法

const before = store => storeDispatch => action => {
    console.log("before", action.type, store.getState())
    return storeDispatch(action)
}
const after = store => storeDispatch => action => {
    let result = storeDispatch(action)
    console.log("after", action.type, store.getState())
    return result
}

最終的完整代碼

import {createStore} from "redux"

// reducer
function counter(state = 0, action) {
    switch (action.type) {
        case "INCREMENT":
            return state + 1
        default:
            return state
    }
}
// 創(chuàng)建 store
let store = createStore(counter)

// action
const ACTION_INCREMENT = "INCREMENT"

// action creator
const increment = () => {
    return {
        type: ACTION_INCREMENT
    }
}

// 前中間件
const before = store => storeDispatch => action => {
    console.log("before", action.type, store.getState())
    return storeDispatch(action)
}

// 后中間件
const after = store => storeDispatch => action => {
    let result = storeDispatch(action)
    console.log("after", action.type, store.getState())
    return result
}

// 應用中間件
const applyMiddleware = (store, ...middlewares) => {
    middlewares.reverse()
    let storeDispatch = store.dispatch
    middlewares.forEach(middleware => {
        storeDispatch = middleware(store)(storeDispatch)
    })
    // store.dispatch = storeDispatch
    return {...store, ...{dispatch: storeDispatch}}
}

// 返回了新的 store
store = applyMiddleware(store, before, after)

// 發(fā)出 action 
store.dispatch(increment())

0x002 redux applyMiddleware
前面寫了一個applyMiddleware方法,雖然可以用,但是官方其實也提供了這個方法,并且比我們寫的更好一點
const before = store => storeDispatch => action => {
    console.log("before", action.type, store.getState())
    return storeDispatch(action)
}
const after = store => storeDispatch => action => {
    let result = storeDispatch(action)
    console.log("after", action.type, store.getState())
    return result
}
let store = createStore(counter, applyMiddleware(before, after))
store.dispatch(increment())
可以看出來,相較于我們自己寫的`applyMiddleware`,官方提供的可以直接傳遞給`createStore`,而無需在次對`store`進行操作。
0x003 異步action
const before = store => storeDispatch => action => {
    console.log("before", action.type, store.getState())
    return storeDispatch(action)
}
const after = store => storeDispatch => action => {
    let result = storeDispatch(action)
    console.log("after", action.type, store.getState())
    return result
}
const asyncAction=()=>{
    return (dispatch)=>{
        setInterval(()=>{
            dispatch(increment())
        },1000)
    }
}
const asyncMiddleware = store => storeDispatch => action => {
    if (typeof action === "function") {
        return action(storeDispatch)
    } else {
        return storeDispatch(action)
    }
}
let store = createStore(counter, applyMiddleware(asyncMiddleware,before,after))
store.dispatch(asyncAction())

這里寫了一個asyncMiddleware,他判斷傳入的action是否是一個函數(shù),如果是一個函數(shù),那就直接執(zhí)行這個函數(shù),同時將dispatch作為參數(shù),則在asyncAction我們就能直接訪問到dispatch了,就可以在asyncAction適當?shù)臅r候再次dispatch了。
當然一樣的,這樣的中間件也已經(jīng)存在了:redux-thunk,日志的中間件也已經(jīng)存在了:redux-logger

import thunkMiddleware from "redux-thunk"
import { createLogger } from "redux-logger"

const store = createStore(
    counter,
    applyMiddleware(
        thunkMiddleware,
        createLogger()
    )
)
store.dispatch(increment())

查看效果

0x004 資源

源碼

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/97936.html

相關文章

  • Router入門0x201: 從 URL 到 SPA

    摘要:的全稱是統(tǒng)一資源定位符英文,可以這么說,是一種標準,而網(wǎng)址則是符合標準的一種實現(xiàn)而已。渲染器,將組件渲染到頁面上。 0x000 概述 從這一章開始就進入路由章節(jié)了,并不直接從如何使用react-route來講,而是從路由的概念和實現(xiàn)來講,達到知道路由的本質,而不是只知道如何使用react-route庫的目的,畢竟react-route只是一個庫,是路由的一個實現(xiàn)而已,而不是路由本身。 ...

    honmaple 評論0 收藏0
  • Redux 入門

    摘要:系列文章入門本文進階番外篇狀態(tài)管理,第一次聽到這個詞要追溯到去年年底。只讀的唯一改變的方法就是觸發(fā),是一個用于描述已發(fā)生事件的普通對象。沒有特殊情況沒有副作用,沒有請求沒有變量修改,只進行單純執(zhí)行計算。 系列文章: Redux 入門(本文) Redux 進階 番外篇: Vuex — The core of Vue application 狀態(tài)管理,第一次聽到這個詞要追溯到去年年...

    shusen 評論0 收藏0
  • redux —— 入門實例 TodoList

    摘要:入門實例前端技術真是日新月異,搞完不搭配個數(shù)據(jù)流都不好意思了。關于的用法,這只是基礎入門的部分,還有的多的搞基操作,比如異步數(shù)據(jù)流和配合。 redux —— 入門實例 TodoListshowImg(https://segmentfault.com/img/bVtSeH); Tip 前端技術真是日新月異,搞完 React 不搭配個數(shù)據(jù)流都不好意思了。滿懷期待的心去翻了翻 flux,簡直...

    SKYZACK 評論0 收藏0
  • Redux技術架構簡介(二)-- 異步實現(xiàn)

    摘要:異步實現(xiàn)設計需要增加三種通知異步請求發(fā)起的異步請求成功的異步請求失敗的示例代碼如下返回參數(shù)完全可以自定義。這種分別在請求開始前,請求成功后,請求失敗后發(fā)送。表示數(shù)據(jù)的有效性,他的作用是在異步請求發(fā)送失敗后,告訴當前的數(shù)據(jù)是過時的數(shù)據(jù)。 說明:對Redux不了解的同學可先看看這篇文章Redux技術架構簡介(一) 前言 這里說的Redux異步實現(xiàn),是專指Redux中的異步Action實現(xiàn),...

    wuaiqiu 評論0 收藏0
  • Redux:Middleware你咋就這么難

    摘要:接下來的函數(shù)就有點難度了,讓我們一行一行來看。上面實際的含義就是將數(shù)組每一個執(zhí)行的返回值保存的數(shù)組中。需要注意的是,方法返回值并不是數(shù)組,而是形如初始值的經(jīng)過疊加處理后的操作。從而實現(xiàn)異步的。   這段時間都在學習Redux,感覺對我來說初學難度很大,中文官方文檔讀了好多遍才大概有點入門的感覺,小小地總結一下,首先可以看一下Redux的基本流程:showImg(https://segm...

    superPershing 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<