沐鳴註冊_如何利用 React Hooks 管理全局狀態

示例代碼: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={useRooGlobalService()}>
      <div>
        <Button />
        <Panel />
      </div>
    </GlobalService.Provider>
  );
};

// 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>;
};

(完)

作者:幾乎一米八的徐某某

出處:Aero Blog (https://www.cnblogs.com/xhyccc/)


站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/10059