」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在不相關的 React 元件之間共用狀態

在不相關的 React 元件之間共用狀態

發佈於2024-08-07
瀏覽:108

想要展示如何在 React 元件之間共享任何可序列化的數據,例如NextJS 中的客戶端元件。

我們有一些不相關的元件:

Example app UI

讓我們建立一個包含初始狀態的物件

export const state: { count: number } = { count: 0 };

我們可以將資料儲存在 Map 或 WeakMap 中,狀態將是存取它的鍵。另外,還需要一個訂閱者陣列。

const stateMap = new WeakMap();
const subscribers: (() => void)[] = [];

現在讓我們編寫一個鉤子來訂閱資料更改。

export function useCommonState(stateObj: T) {
  // more efficient than `useEffect` since we don't have any deps
  React.useInsertionEffect(() => {
    const cb = () => {
      const val = stateMap.get(stateObj);
      _setState(val!);
    };
    // subscribe to events
    subscribers.push(cb);

    return () => {
      subscribers.slice(subscribers.indexOf(cb), 1);
    };
  }, []);
}

現在讓我們加入與獲取和設定狀態相關的邏輯

  // all instances of hook will point to same object reference
  const [state, _setState] = React.useState(() => {
    const val = stateMap.get(stateObj) as T;
    if (!val) {
      stateMap.set(stateObj, stateObj)
      return stateObj
    }
    return val
  });

  const setState = React.useCallback((newVal: object) => {
    // update value
    stateMap.set(stateObj, newVal);
    // notify all other hook instances
    subscribers.forEach((sub) => sub());
  }, []);

  return { state, setState };

現在可以在 3 個元件中使用它,例如

import { state as myState } from './state';
//...

const { state, setState } = useCommonState(myState);


// ...
Component A
Count: {state.count}

Final app

您可以在這裡查看它是如何工作的 https://stackblitz.com/~/github.com/asmyshlyaev177/react-common-state-example
或在這裡https://codesandbox.io/p/github/asmyshlyaev177/react-common-state-example/main
或在github https://github.com/asmyshlyaev177/react-common-state-example

根據這個原則查看我的 NextJS 函式庫 https://github.com/asmyshlyaev177/state-in-url

Tnx 供閱讀。

版本聲明 本文轉載於:https://dev.to/asmyshlyaev177/sharing-state-between-unrelated-react-components-4aia?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3