如何利用 React Hooks 管理全域狀態
本文寫于 2020 年 1 月 6 日
示例代碼:https://github.com/AerospaceXu/hooks-soa
React 社區最火的全域狀態管理庫必定是 Redux,但是 Redux 本身就是為了大型管理資料而妥協設計的——這就會讓一些小一點的應用一旦用上 Redux 就變得復雜無比,
后來又有了 Mobx,它對于小型應用的狀態管理確實比 Redux 簡單不少,可是不得不說 Mobx+React 簡直就是一個繁瑣版本的 Vue,
另外不管是 react-redux 還是 mobx,他們使用的時候都非常復雜,需要你去組件函式或是組件類上修修改改,我個人從審美上來說就不是很喜歡,
后來用了 Angular 之后,我就開始對 SOA 產生好感,ng 的 Service 與依賴注入我都覺得非常漂亮,
Service 是 Angular 的邏輯復用形式,并且解決了共享狀態的問題,那 React 的自定義 Hook 可以達到類似的效果嘛?
可以,并且會比 Angular 更簡潔,
自定義 Service
材料:useXxxx(自定義 hook), createContext, useContext,
我們做一個最簡單的計數器吧:一個 button,一個 panel,button 用來增加,panel 用來展示,
const App: React.FC = () => {
return (
<div>
<Button />
<Panel />
</div>
);
};
然后我們來定義我們的 Service:
// services/global.service.ts
interface State {
count: number;
handleAdd: () => void;
}
export const GlobalService = createContext<State>(null);
我們選擇讓一個 Context 成為一個 Service,這是因為我們可以利用 Context 的特性來進行狀態共享,
然后我們創建一個自定義 Hook,并且在 Context.provider 中傳入該 Root Service:
// services/global.service.ts
export const useRootGlobalService = () => {
const [count, setCount] = useState<number>(0);
const handleAdd = useCallback(() => {
setCount((n) => n + 1);
}, []);
return {
count,
handleAdd,
};
};
接著我們再創建一個自定義 Hook,讓我們可以隨時拿到該 Service:
// services/global.service.ts
export const useGlobalService = () => useContext(GlobalService);
接著我們就可以運用了
// App.tsx
import { GlobalService, useRooGlobalService } from './services/global.service';
const App: React.FC = () => {
return (
<GlobalService.Provider value=https://www.cnblogs.com/xhyccc/p/{useRooGlobalService()}>
);
};
// Button.tsx
import { useGlobalService } from'../services/global.service';
const Button: React.FC = () => {
const { handleAdd } = useGlobalService();
return <button onClick={() => handleAdd()}>+</button>;
};
// Panel.tsx
import { useGlobalService } from '../services/global.service';
const Panel: React.FC = () => {
const { count } = useGlobalService();
return <h2>{count}</h2>;
};
(完)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/245598.html
標籤:JavaScript
上一篇:百度地圖 - 基礎學習(6): 滑鼠繪制工具添加、圖形幾何運算(長度、面積等)
下一篇:JavaScript(六)-函式
