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

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

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

想要展示如何在 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]刪除
最新教學 更多>
  • 如何使用組在MySQL中旋轉數據?
    如何使用組在MySQL中旋轉數據?
    在關係數據庫中使用mysql組使用mysql組來調整查詢結果。在這裡,我們面對一個共同的挑戰:使用組的組將數據從基於行的基於列的基於列的轉換。通過子句以及條件匯總函數,例如總和或情況。讓我們考慮以下查詢: select d.data_timestamp, sum(data_id = 1 tata...
    程式設計 發佈於2025-02-07
  • 'exec()
    'exec()
    Exec對本地變量的影響: exec function,python staple,用於動態代碼執行的python staple,提出一個有趣的Query:它可以在函數中更新局部變量嗎? python 3 Dialemma 在Python 3中,以下代碼shippet無法更新本地變量,因為人...
    程式設計 發佈於2025-02-07
  • 如何干淨地刪除匿名JavaScript事件處理程序?
    如何干淨地刪除匿名JavaScript事件處理程序?
    在這里工作/},false); 不幸的是,答案是否。除非在Creation中存儲對處理程序的引用。 要解決此問題,請考慮將事件處理程序存儲在中心位置,例如頁面的主要對象,請考慮將事件處理程序存儲在中心位置,否則無法清理匿名事件處理程序。 。這允許在需要時輕鬆迭代和清潔處理程序。
    程式設計 發佈於2025-02-07
  • 如何在整個HTML文檔中設計特定元素類型的第一個實例?
    如何在整個HTML文檔中設計特定元素類型的第一個實例?
    [2單獨使用CSS,整個HTML文檔可能是一個挑戰。 the:第一型偽級僅限於與其父元素中類型的第一個元素匹配。 以下CSS將使用添加的類樣式的第一個段落: }
    程式設計 發佈於2025-02-07
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    如何為JavaScript對像變量創建動態鍵,嘗試為JavaScript對象創建動態鍵,使用此Syntax jsObj['key' i] = 'example' 1;將不起作用。正確的方法採用方括號:他們維持一個長度屬性,該屬性反映了數字屬性(索引)和一個數字屬性的數量。標準對像沒有模仿這...
    程式設計 發佈於2025-02-07
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    使用(1)而不是(;;)會導致無限循環的性能差異? 現代編譯器,(1)和(;;)之間沒有性能差異。 是如何實現這些循環的技術分析在編譯器中: perl: S-> 7 8 unstack v-> 4 -e語法ok 在GCC中,兩者都循環到相同的彙編代碼中,如下所示:。 globl t_時 ...
    程式設計 發佈於2025-02-07
  • 如何使用PHP從XML文件中有效地檢索屬性值?
    如何使用PHP從XML文件中有效地檢索屬性值?
    從php 您的目標可能是檢索“ varnum”屬性值,其中提取數據的傳統方法可能會使您感到困惑。 - > attributes()為$ attributeName => $ attributeValue){ echo $ attributeName,'=“',$ a...
    程式設計 發佈於2025-02-07
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。 To resolve this issue and ensure scripts execute on subsequent page visits, Firefox...
    程式設計 發佈於2025-02-07
  • 如何使用替換指令在GO MOD中解析模塊路徑差異?
    如何使用替換指令在GO MOD中解析模塊路徑差異?
    克服go mod中的模塊路徑差異 coreos/bbolt:github.com/coreos/ [email受保護]:解析go.mod:模塊將其路徑聲明為:go.etcd.io/bbolt `要解決此問題,您可以在go.mod文件中使用替換指令。只需在go.mod的末尾添加以下行:[&& &...
    程式設計 發佈於2025-02-07
  • 可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    </main> <section> ,但无法使其正常工作,如您所见。任何洞察力都将不胜感激! display:grid; { position:sticky; top:1em; z-index:1 1 ; { { { pos...
    程式設計 發佈於2025-02-07
  • Trie簡介(前綴樹)
    Trie簡介(前綴樹)
    Trie 是一種類似樹的數據結構,用於有效存儲和搜索字符串,尤其是在諸如AutoComplete,Spell Checking和IP路由之類的應用程序中。 Trie的關鍵特性: nodes :每個節點代表一個字符。 :root節點是空的,並用作起點。 :每個節點最多有26個...
    程式設計 發佈於2025-02-07
  • 如何處理PHP MySQL中的分頁和隨機訂購以避免重複和不一致?
    如何處理PHP MySQL中的分頁和隨機訂購以避免重複和不一致?
    [ php mysql分頁與隨機訂購:克服重複和頁面一致性挑戰 1。在後續頁面上排除先前看到的結果,以防止先前顯示的結果在隨機訂購時重新出現在隨機訂購時:在會話變量中存儲ID作為逗號分隔的列表。 修改您的sql查詢以排除這些IDS: 2。確保第一頁上的不同結果隨機訂購將使很難在第一頁上保證獨特的...
    程式設計 發佈於2025-02-07
  • 哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    哪種方法更有效地用於點 - 填點檢測:射線跟踪或matplotlib \的路徑contains_points?
    在Python 射線tracing方法Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a路徑對象表示多邊形。它檢查給定點是否位於定義路徑內。 T...
    程式設計 發佈於2025-02-07
  • 為什麼Microsoft Visual C ++無法正確實現兩台模板的實例?
    為什麼Microsoft Visual C ++無法正確實現兩台模板的實例?
    [2明確擔心Microsoft Visual C(MSVC)在正確實現兩相模板實例化方面努力努力。該機制的哪些具體方面無法按預期運行? 背景:說明:的初始Syntax檢查在範圍中受到限制。它未能檢查是否存在聲明名稱的存在,導致名稱缺乏正確的聲明時會導致編譯問題。 為了說明這一點,請考慮以下示例:一個...
    程式設計 發佈於2025-02-07
  • 版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    版本5.6.5之前,使用current_timestamp與時間戳列的current_timestamp與時間戳列有什麼限制?
    在默認值中使用current_timestamp或mysql版本中的current_timestamp或在5.6.5 這種限制源於遺產實現的關注,這些限制需要為Current_timestamp功能提供特定的實現。消息和相關問題 `Productid` int(10)unsigned not ...
    程式設計 發佈於2025-02-07

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

Copyright© 2022 湘ICP备2022001581号-3