簡體   English   中英

React Hooks - 沒有上下文的全局狀態

[英]React Hooks - Global state without context

我正在實現一個鈎子“useUserPosts”,它應該在我的應用程序的幾個路由中使用。

由於我已經有一個上下文“PostsContext”,它在數據更改時重新呈現我的卡片(totalLikes、totalComments、描述等),我決定避免創建另一個名為“UserPostsContext”的上下文,其目的是返回用戶帖子大批。

我知道,為什么不改用 PostsContext 呢?...

答案是,在 PostsContext 中,為了避免性能問題,我存儲了一個映射(鍵、值),以便在 O(1) 中獲取/更新帖子動態數據,這僅在我的組件中有用(所以, 基本上是用來同步卡片的)

在 React 中創建鈎子來處理全局狀態而不使用 Context API 或 Redux 是否可能/常見做法?

我的意思是,像

// Global State Hook
const useUserPosts = (() => {
   const [posts, setPosts] = useState({});
   return ((userId) => [posts[id] ?? [], setPosts]);
})();


// Using the Global State Hook
function useFetchUserPosts(userId) {
   const [posts, setPosts] = useUserPosts(userId);
   const [loading, setLoading] = useState(!posts.length);
   const [error, setError] = useState(undefined);

   const cursor = useRef(new Date());
   const hasMoreToLoad = useRef(false);
   const isFirstFetch = useRef(true);

   const getUserPosts = async () => {
      // ...
   }

   return { posts, loading, error, getUserPosts };
}

注意:我這樣做的目的是:

1. Reproduce some kind of cache
2. Synchronize the fetched data of each stack screen that is mounted in order to reduce backend costs
3. Synchronize user posts deletions

即使我認為創建一個新的全局狀態是最好的解決方案,如果你真的想避免它,你可以創建自己的如下:

export class AppState {
  private static _instance: AppState;


  public state = new BehaviorSubject<AppStateType>({});

  /**
   * Set app state without erasing the previous values (values not available in the newState param)
   * */
  public setAppState = (newState: AppStateType) => {
    this.state.next({ ...this.state, ...newState });
  };

  private constructor() {}

  public static getInstance(): AppState {
    if (!AppState._instance) {
      AppState._instance = new AppState();
    }

    return AppState._instance;
  }
}

使用這種類型:

export type AppStateType = {
  username?: string;
  isThingOk?: boolean;
  arrayOfThing?: Array<MyType>;
...
}

並以這種方式使用它:

const appState = AppState.getInstance();
...
...
appState.setAppState({ isThingOk: data });
...
...
appState.state.subscribe((state: AppStateType) => {// do your thing here});

不確定這是創建自己的狀態的最佳方式,但效果很好。 隨意調整它以滿足您的需求。

我可以建議你使用一些輕狀態管理庫作為zustandhttps : //github.com/pmndrs/zustand

您可以使用此庫避免重新渲染並指定重新渲染僅希望您想要更改或以某種方式更改的數據與某些功能來比較舊值和新值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM