React Graft
Turns a hook into a context: write the state once, read it anywhere below its provider.
Usage
Write a hook, pass it to createGraft, mount the provider, and read the value with use().
tsx
export const GraftLikes = createGraft({
name: "GraftLikes",
graft: useGraft,
});
function useGraft({ start = 0 }: { start?: number }) {
const [value, setValue] = useState(start);
const like = useCallback(() => setValue((count) => count + 1), []);
return { value, like };
}
<GraftLikes.Provider start={10}>
<LikeButton />
</GraftLikes.Provider>
const { value, like } = GraftLikes.use();What you get
- Typed props. The hook's options become the provider's props, and what it returns is what
use()returns. Nothing to declare twice. - No empty context. The context itself is never exported, and
use()throws, naming the graft, when it is called outside the provider. - A place for side effects.
injectruns extra hooks inside the provider, like syncing the URL or saving to storage.
Limits
It is plain React: a hook, a provider and a context. No proxies and no selectors, so when the value changes, every component that reads it re-renders.