首頁 > web前端 > js教程 > 主體

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

WBOY
發布: 2024-07-17 06:51:30
原創
1121 人瀏覽過

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

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

Example app UI

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

export const state: { count: number } = { count: 0 };
登入後複製

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

const stateMap = new WeakMap<object, object>();
const subscribers: (() => void)[] = [];
登入後複製

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

export function useCommonState<T extends object>(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<typeof stateObj>(() => {
    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);

<button
  onClick={() => setState({ count: state.count + 1 })}
  className="p-2 border"
>
  +
</button>
// ...
Component A<div>Count: {state.count}</div>
登入後複製

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 閱讀。

以上是在不相關的 React 元件之間共用狀態的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!