由於平時工作中使用
vue
比較多,故而在全局狀態管理上必然離不開vuex
這個依賴庫,使用起來尤爲順手。最近在搭建公司前端的配置中心時,考慮到維護性和可擴展性的需求,想使用typescript
作爲基礎,權衡之下選擇了對typescript
支持更友好的react
作爲基礎框架,那麼除了mobx
之外,也嘗試了redux
,雖說和vuex
的原理差不多,但是用起來卻十分繁瑣,於是看了一下其他大佬的文章,發現結合react
的hook
是可以自己創建一個輕量級的’redux’來管理一些比較頂層的狀態。
一、技術準備
要模仿redux的store,其實依賴了react的context api,由於react的一下props經常面臨多層透傳的情況,導致維護性不高,於是官方提供了context的上下文api,讓所有子組件共享全局的狀態。
因此,要完成這個“輕量版”的redux,需要提前瞭解一下的知識點:
不熟練的小夥伴,建議點擊以上傳送門提前熟悉瞭解一下API的用法,對於已經理解並且使用了一段時間的小夥伴,相信下面的內容也不用看了,憑着自己的理解與思考其實很容易就能寫出一個非常輕量的‘redux’
二、模擬Provider組件
在redux的使用中,store的數據很巧妙地用了組件的屬性透傳下去組件樹裏,像這樣:
import { Provider } from 'react-redux';
import store from './store';
import App from './App.jsx';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
因此,我們也可以手動製作一個Provider組件出來進行store的透傳:
在項目的根目錄下創建一個Provider.js文件:
import React,{Component} from 'react';
export const storeContext = React.createContext();
export default class Provider extends Component{
render(){
return (
<storeContext.Provider value={this.props.store}>
{this.props.children}
</storeContext.Provider>
)
}
}
三、模擬reducer
redux是通過接收aciton執行對應的reducer來更新數據的,因此我們需要用到一個React hook來模擬reducer的行爲,恰好React提供了useReducer的API可以方便我們在局部組件裏方便地管理數據。因此,爲了模擬出redux的效果,我們需要從“局部”變爲“全局”。
首先,我們把reducer的邏輯先解耦成單獨的文件方便維護,在自定義的目錄下建一個Reducer.js:
export const initialState = {
date:'2月11日'
count:0
}
export const reducer = (state, action)=>{
switch (action.type) {
case 'TEST':
return {...initialState,count:count+1}
default:
return initialState;
}
}
隨後,我們在App.jsx中,開始模擬redux:
import React,{useReducer} from 'react';
import Provider from './Provider';
import Child from './views/child';
import {initialState,reducer} from './Reducer';
import './App.css';
function App() {
const [state,dispatch] = useReducer(reducer,initialState);
return (
<div className="App">
<Provider store={{state,dispatch}}>
<Child/>
</Provider>
</div>
);
}
export default App;
至此,我們已經成功完成了一個輕量極地redux組件了,至於怎麼使用,並且它和真實redux的利弊,將在下一篇中分享;