question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Discussion: adding a `createProviderFromHook` utility

See original GitHub issue

I absolutely love this library, and am using it in several big projects. So let me start with a thank you! I wanted to suggest a small feature. I am more than happy to create a PR, but wanted to discuss it first.

The problem: boilerplate

When working with Context (both the native React context and the Context of this library), especially with hooks, I find myself repeating this same exact boilerplate:

  1. Create a context
  2. Export a custom Provider that wraps context.Provider
  3. Export a custom hook that wraps useContext/useContextSelector but throws if the Provider is missing
  4. Create a type definition for the context’s value

For example, here’s the boilerplate required for this repo’s Usage example:

const MISSING_PROVIDER = Symbol('MISSING_PROVIDER');
const context = createContext<CounterInfo>(MISSING_PROVIDER);

type CounterInfo = [ { count1: number, count2: number }, setState: any ];

export const CounterProvider = ({ children }) => (
  <context.Provider value={useState({ count1: 0, count2: 0 })}>
    {children}
  </context.Provider>
);

export const useCounterSelector = (selector: any) => {
  return useContextSelector(context, (value) => {
    if (value === MISSING_PROVIDER) throw new Error("Missing `CounterProvider`");
    return selector(value);
  });
};

The solution: createProviderFromHook

All of this boilerplate can be eliminated! Implementation details aside, here’s the finished result:

export const [ CounterProvider, useCounterSelector ] = createProviderFromHook(() => useState({ count1: 0, count2: 0 }));

This syntax is inspired by the wonderful constate library,.

A few noteworthy things about this createProviderFromHook function:

  1. The raw context is kept private, so you don’t have to remember to import createContext from the right place
  2. The custom Provider boilerplate is eliminated.
  3. The custom useCounterSelector boilerplate is eliminated, and automatically checks for missing providers.
  4. Strongly typed! All type arguments are correctly inferred, no manual type defs needed.

Let me know what you think about adding this utility. The implementation would not be big or cause bloat, and this feature would be extremely useful to anyone using this library.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
dai-shicommented, Apr 17, 2022

That’s exactly what I do in react-tracked with useSelector. So, I don’t want the duplication.

More importantly, this library is something that will be obsoleted when React provides a native solution. So, we shouldn’t add a new feature.

If react-tracked doesn’t fit for you (as it also has useTrackedState), you might want to create a new library. (and list in https://github.com/dai-shi/use-context-selector#projects-that-use-use-context-selector)

0reactions
scottrippeycommented, Apr 18, 2022

Oh, that’s awesome to hear. I wasn’t aware of this experiment; I will eagerly start watching for that! Thanks for the heads up.

Read more comments on GitHub >

github_iconTop Results From Across the Web

History for src - ampproject/amphtml · GitHub
The AMP web component framework. Contribute to ampproject/amphtml development by creating an account on GitHub.
Read more >
React useContextSelector hook in userland - BestofReactjs
Discussion : adding a `createProviderFromHook` utility. I absolutely love this library, and am using it in several big projects.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found