從零開始寫一個 redux(第一講)

相關(guān)倉庫:
https://github.com/mcuking/mini-redux

首先我們不考慮react-redux,先思考如何實現(xiàn)redux的功能。
redux根據(jù)reducer(根據(jù)舊全局state和action生成新的全局state)生成全局狀態(tài)樹store。即

store = createStore(reducer)

下面我們就首先實現(xiàn)createStore機制,代碼如下,其中:

  • currentState用來存儲當前應(yīng)用的全局狀態(tài)

  • currentListeners數(shù)組用來存儲當前的所有監(jiān)聽函數(shù),每當store有變化,store就會調(diào)用傳入subscribe的監(jiān)聽函數(shù)

同時生成的store具有如下API:

  • getState用來返回當前的state

  • subscribe用來訂閱監(jiān)聽,即將所有監(jiān)聽函數(shù)push到currentListeners

  • dipatch用來派發(fā)action,使得reducer可以根據(jù)action和舊的state生成新的state,同時執(zhí)行傳入currentListeners的所有的監(jiān)聽函數(shù)

當?shù)谝淮武秩緯r,需要生成一個初始化的store,因此需要派發(fā)一個不存在的action,action的type命名盡量特殊,不與使用者的沖突,命名為@@redux/INIT1。

export function createStore(reducer) {
    let currentState = {}
    let currentListeners = []

    function getState() {
        return currentState
    }

    // 傳入監(jiān)聽函數(shù)
    function subscribe(listener) {
        currentListeners.push(listener)
    }

    function dispatch(action) {
        // reducer根據(jù)老的state和action計算新的state
        currentState = reducer(currentState, action)
        // 當全局狀態(tài)變化時,執(zhí)行傳入的監(jiān)聽函數(shù)
        currentListeners.forEach(v => v())
        return action
    }

    dispatch({type: '@@redux/INIT1'}) // 初始化全局狀態(tài)
    return { getState, subscribe, dispatch }
}

這樣我們最簡版本的redux就已經(jīng)實現(xiàn)了,下面是使用該最簡版redux的應(yīng)用代碼

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from './mini-redux'
import App from './App'

// 通過reducer建立store(reducer會根據(jù)老的state和action,生成新的state)
function counter(state=0, action) {
    switch(action.type) {
        case '買一套房':
            return state + 1
        case '賣一套房':
            return state - 1
        default:
            return 10
    }
}

const store = createStore(counter)
// console.log(store, 'store')
const init = store.getState()


function listener() {
    const current = store.getState()
    // console.log(`現(xiàn)有房子${current}套`)
}

// 監(jiān)聽,store有變化,store就會調(diào)用傳入subscribe的函數(shù)
store.subscribe(listener)

// 派發(fā)事件, 傳遞action
store.dispatch({type: '買一套房'})
store.dispatch({type: '賣一套房'})
store.dispatch({type: '買一套房'})

接下來我們將在此基礎(chǔ)上,實現(xiàn)react-redux功能,以便在react中更優(yōu)雅的使用redux進行全局狀態(tài)管理。

另外最近正在寫一個編譯 Vue 代碼到 React 代碼的轉(zhuǎn)換器,歡迎大家查閱。

https://github.com/mcuking/vue2react

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容