九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
如何利用 React Hooks 管理全局狀態(tài)

如何利用 React Hooks 管理全局狀態(tài)

本文寫于 2020 年 1 月 6 日

React 社區(qū)最火的全局狀態(tài)管理庫必定是 Redux,但是 Redux 本身就是為了大型管理數(shù)據(jù)而妥協(xié)設(shè)計的——這就會讓一些小一點的應(yīng)用一旦用上 Redux 就變得復(fù)雜無比

后來又有了 Mobx,它對于小型應(yīng)用的狀態(tài)管理確實比 Redux 簡單不少。可是不得不說 Mobx+React 簡直就是一個繁瑣版本的 Vue。所以我也不太喜歡,不如直接用 Vue3。

總而言之,不管是 react-redux 還是 mobx,他們使用的時候都非常復(fù)雜,甚至需要你去組件函數(shù)或是組件類上修修改改,從審美角度上來說就令人不太喜歡。

直到后來某一天用了 Angular,我就開始對 SOA 產(chǎn)生好感,ng 的 Service 的寫法與依賴注入控制反轉(zhuǎn)著實驚艷到了我。

Service 是 Angular 的邏輯復(fù)用方法,并且解決了共享狀態(tài)的問題,那 React 的自定義 Hook 可以達(dá)到類似的效果嘛?

可以,并且會比 Angular 更簡潔!??!

什么是 Service

我們先來想一下,Service 到底是什么?

  • Service 包含 n 個方法;
  • Service 包含有狀態(tài);
  • Service 應(yīng)該是個單例。
  • 這些方法與狀態(tài)應(yīng)該是高度整合的,一個 Service 解決的是一個模塊的問題。

例如下面這個負(fù)責(zé) Todo List 記錄的 Service:

class TodoRecordService {
  private todoList: Record[] = [];

  get getTodoList() {
    return this.todoList;
  }

  public addRecord(newRecord: Record) {
    this.todoList.push(newRecord);
  }

  public deleteRecord(id: string) {
    this.todoList = this.todoList.filter((record) => record.id !== id);
  }

  public getRecord(id: string) {
    const targetIndex = this.todoList.findIndex((record) => record.id === id);
    return { index: targetIndex, ele: this.todoList[targetIndex] };
  }
}

自定義 Service

那我們用 React 如何實現(xiàn)一個狀態(tài)共享的單例呢?

使用 ContextuseContext 即可。

接下來我們做一個最簡單的計數(shù)器吧:一個負(fù)責(zé)計數(shù)的 button,一個負(fù)責(zé)顯示當(dāng)前數(shù)值的 panel。

const App: React.FC = () => {
  return (
    <div>
      <Button />
      <Panel />
    </div>
  );
};

然后我們來定義我們的 Service:

interface State {
  count: number;
  handleAdd: () => void;
}

export const CountService = createContext<State>(null);

我們選擇讓一個 Context 成為一個 Service,這是因為我們可以利用 Context 的特性來進(jìn)行狀態(tài)共享,達(dá)到單例的效果。

但是光這樣還不行,我們想讓 count 擁有響應(yīng)性,就必須使用 useState(或者其他 hook)來創(chuàng)建。

因此需要一個自定義 Hook,并且在 Context.Provider 中傳入 Providervalue 值:

interface State {
  count: number;
  handleAdd: () => void;
}

export const CountService = createContext<State>(null);

export const useRootCountService = () => {
  const [count, setCount] = useState<number>(0);
  const handleAdd = useCallback(() => {
    setCount((n) => n + 1);
  }, []);

  return {
    count,
    handleAdd,
  };
};

那么在組建中,我們?nèi)绾问褂?Service 呢?

非常簡單:

const App: React.FC = () => {
  const countService = useContext(CountService);

  return <div>{countService.count}</div>;
};

所以計數(shù)器的完整代碼應(yīng)該這么寫:

import { CountService, useRootCountService } from './service/count.service';

const App: React.FC = () => {
  return (
    <CountService.Provider value={useRooCountService()}>
      <div>
        <Button />
        <Panel />
      </div>
    </CountService.Provider>
  );
};

// Button.tsx
import { CountService } from '../services/global.service';

const Button: React.FC = () => {
  // 注意,此處是故意寫復(fù)雜了,是為了凸顯跨組件狀態(tài)管理的特性
  const countService = useContext(CountService);
  return <button onClick={() => countService.handleAdd()}>+</button>;
};

// Panel.tsx
import { CountService } from '../services/global.service';

const Panel: React.FC = () => {
  const countService = useContext(CountService);
  return <h2>{countService.count}</h2>;
};

hooks 與 Service

對于小組件而言,剛剛的寫法已經(jīng)足夠了。

但是要知道,Service 是高度集中的某個模塊的狀態(tài)與方法,我們不能保證 Service 的方法可以直接用到組件的邏輯中去。

所以需要我們在組件內(nèi)部對于邏輯進(jìn)行二次拼裝。

但是把邏輯直接寫到組件里面是一件非常惡劣的事情?。?!

幸好,React 有了 hooks 讓我們?nèi)コ殡x邏輯代碼。

const useLogic1 = () => {
  // 在 hook 中獲取服務(wù)
  const xxxService = useContext(XxxService);
  // ...
  const foo = useCallback(() => {
    // ...
    xxxService.xxxx();
    // ...
  }, []);

  return {
    // ...
    foo,
  };
};

const SomeComponent: React.FC = () => {
  // 復(fù)用邏輯
  const { a, b, foo } = useLogic1(someParams);
  const { c, bar } = useLogic2();

  return (
    <div>
      <button onClick={() => bar()}>Some Operation</button>
    </div>
  );
};

這種形式的組件,便是我們的目標(biāo)。

(完)

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
React 實戰(zhàn) Todolist (上)
前端框架及項目面試 聚焦
?如何使用 GraphQL 構(gòu)建 TypeScript React 應(yīng)用
React中useEffect的源碼解讀
hooks 與 animejs
干貨 | React Hook的實現(xiàn)原理和最佳實踐
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服