接着上一篇繼續記錄一下關於使用useContext和useReducer結合創建的readux使用方法,還不瞭解如何創建的請參考:使用React-Hook創建輕量版的Redux(上)
一、創建connet工具
緊接着上一篇的步驟,我們在App.jsx中使用了自己創建的Provider包裹了組件,那麼,我們按照平時使用react-redux
透傳store
的參數到子組件的props
時,都會使用connet
,爲了方便,我們可以使用hook定義一個connet
函數用於獲取state和dispatch:
在src或任意目錄下新建一個connet.js文件,寫入:
import {useConext} from 'react';
export default function useConnect(props){
return useContext(props);
}
二、在組件中使用
接着,我們就可以在任意的子組件中使用useConnet
來或去redux中的state和dispatch了。比如在其中一個子組件child中:
import React,{useContext} from 'react';
import useConnect from './connect';
import {storeContext} from './store';
import OtherChild from './OtherChild';
function Child() {
//必須放入storeContext作爲全局上下文,因爲整個redux的狀態其實是基於context記錄的
const {state,dispatch}= useConnect(storeContext);
return (
<div className="child">
<p>公司:{state.company}</p>
<p>人數:{state.count}</p>
<button onClick={()=>dispatch({type:'TEST'})}>changCount</button>
<p>deep child:</p>
<OtherChild/>
</div>
);
}
export default Child;
爲了驗證,是否全局都能訪問到最新的state
,可以看到我們在上面的Child
組件中,還內嵌了OtherChild
組件,在OtherChild
組件中我們同樣可以使用useConnet
獲取最新的state以及dispatch函數:
import React,{useContext} from 'react';
import {storeContext} from './store';
import useConnect from './connect';
export default function OeepChild(){
const {state} = useConnect(storeContext);
return (
<div>
{state.count}
</div>
)
}
運行後可以清晰地發現,只要在Child
組件中改變了count
的值,那麼OtherChild
也會拿到最新的值,一個輕量版的redux就完成了!
三、和真正的redux比較
雖然使用hook+context能完成輕量的redux功能,但是和真正的redux還是有些區別的,下面用表格來說明:
自定義Redux | Redux | |
---|---|---|
模塊化 | 聚集在context層,遇到多個模塊reducer的情況無法解耦 | 可以解耦成多個reducer,最後合併到一起,方便維護 |
功能 | 只是利用了context作爲全局的state儲存和修改,一些靈活的異步處理沒有對應的中間價支持 | 通過redux-thunk、redux-saga等中間價能應付不同場景的異步需求 |
性能 | 因爲用的是context,只要store裏的值改變,那麼所有使用到context的組件都會強制重渲染 | 只變更對應的組件狀態 |