Discussion: adding a `createProviderFromHook` utility
See original GitHub issueI 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:
- Create a context
- Export a custom Provider that wraps
context.Provider
- Export a custom hook that wraps
useContext/useContextSelector
but throws if theProvider
is missing - 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:
- The raw
context
is kept private, so you don’t have to remember to importcreateContext
from the right place - The custom
Provider
boilerplate is eliminated. - The custom
useCounterSelector
boilerplate is eliminated, and automatically checks for missing providers. - 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:
- Created a year ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
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)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.