【问题标题】:React Hooks - Global state without contextReact Hooks - 没有上下文的全局状态
【发布时间】:2021-12-15 08:20:53
【问题描述】:

我正在实现一个钩子“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

【问题讨论】:

    标签: javascript reactjs react-native react-hooks


    【解决方案1】:

    即使我认为创建一个新的全局状态是最好的解决方案,如果你真的想避免它,你可以创建自己的如下:

    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});
    

    不确定这是创建自己的状态的最佳方式,但效果很好。随意调整它以适应您的需求。

    【讨论】:

      【解决方案2】:

      我可以推荐你使用一些光状态管理库,如zustand:https://github.com/pmndrs/zustand

      您可以使用此库避免重新渲染并指定重新渲染只是希望您想要更改的数据或以某种方式更改的数据与某些功能来比较旧值和新值。

      【讨论】:

        猜你喜欢
        • 2019-10-15
        • 1970-01-01
        • 2020-05-11
        • 1970-01-01
        • 2021-03-08
        • 1970-01-01
        • 1970-01-01
        • 2020-11-25
        • 1970-01-01
        相关资源
        最近更新 更多