Skip to content

react-singleton-hook + use-context-selector #435

Description

@rnarcos

I have a utilty function that creates a Context.Provider, and a useContext.

For my specific case, I'd like to use use-context-selector library to improve the performance of my application.

The API for the use-context-selector is: const myContextData = useContextSelector(Context, (state) => state[0].data);
In my function, I create an abstraction for the useContextSelector, like this: (contextSelectorFn) => useContextSelector(Context, contextSelectorFn).

This way, I can use my custom hook directly like: const myUserId = useUserData((state) => state[0].id);.
I'm sort of having a hard time understand how could I simply adhere to this singleton pattern for this use case.

Here's the code for my utility function as of now:

import type { Dispatch, ReactElement, ReactNode, SetStateAction } from 'react';
import { useState } from 'react';
import { createContext, useContextSelector } from 'use-context-selector';

type GlobalState<State> = [State, Dispatch<SetStateAction<State>>];
type Provider = (props: { children: ReactNode }) => ReactElement;
type GlobalContext<State> = <Selected>(
  selector: (value: GlobalState<State>) => Selected,
) => Selected;

function createGlobalStateContext<State>(
  initialState: State,
): [GlobalContext<State>, Provider] {
  const Context = createContext<GlobalState<State>>([initialState, () => {}]);

  const ProviderComponent: Provider = ({ children }) => {
    const [state, setState] = useState<State>(initialState);

    const contextState: GlobalState<State> = [state, setState];

    return <Context.Provider value={contextState}>{children}</Context.Provider>;
  };

  return [
    (contextSelectorFn) => useContextSelector(Context, contextSelectorFn),
    ProviderComponent,
  ];
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions