相關倉庫: github.com/mcuking/min…javascript
首先咱們不考慮react-redux,先思考如何實現redux的功能。 redux根據reducer(根據舊全局state和action生成新的全局state)生成全局狀態樹store。即vue
store = createStore(reducer)
複製代碼
下面咱們就首先實現createStore機制,代碼以下,其中:java
currentState用來存儲當前應用的全局狀態react
currentListeners數組用來存儲當前的全部監聽函數,每當store有變化,store就會調用傳入subscribe的監聽函數git
同時生成的store具備以下API:github
getState用來返回當前的stateredux
subscribe用來訂閱監聽,即將全部監聽函數push到currentListeners數組
dipatch用來派發action,使得reducer能夠根據action和舊的state生成新的state,同時執行傳入currentListeners的全部的監聽函數dom
當第一次渲染時,須要生成一個初始化的store,所以須要派發一個不存在的action,action的type命名儘可能特殊,不與使用者的衝突,命名爲@@redux/INIT1
。函數
export function createStore(reducer) {
let currentState = {}
let currentListeners = []
function getState() {
return currentState
}
// 傳入監聽函數
function subscribe(listener) {
currentListeners.push(listener)
}
function dispatch(action) {
// reducer根據老的state和action計算新的state
currentState = reducer(currentState, action)
// 當全局狀態變化時,執行傳入的監聽函數
currentListeners.forEach(v => v())
return action
}
dispatch({type: '@@redux/INIT1'}) // 初始化全局狀態
return { getState, subscribe, dispatch }
}
複製代碼
這樣咱們最簡版本的redux就已經實現了,下面是使用該最簡版redux的應用代碼
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from './mini-redux'
import App from './App'
// 經過reducer創建store(reducer會根據老的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(`現有房子${current}套`)
}
// 監聽,store有變化,store就會調用傳入subscribe的函數
store.subscribe(listener)
// 派發事件, 傳遞action
store.dispatch({type: '買一套房'})
store.dispatch({type: '賣一套房'})
store.dispatch({type: '買一套房'})
複製代碼
接下來咱們將在此基礎上,實現react-redux功能,以便在react中更優雅的使用redux進行全局狀態管理。
另外最近正在寫一個編譯 Vue 代碼到 React 代碼的轉換器,歡迎你們查閱。