Scope Provider
A lightweight wrapper around React Context that makes passing values down your component tree a lot easier.
Installation
pnpm dlx shadcn add https://meeshan.dev/r/scope-provider.jsonWhy do you need this?
In React apps, passing data through many levels of components can quickly turn into "prop drilling" — where you're passing props through components that don't even need them just to get them to where they're actually used. It's a mess to maintain and even harder to read.
I built ScopeProvider and useScopeCtx to fix this. They use React's Context API under the hood to let your components access shared data without all that annoying prop drilling.
Sure, you could use React's built-in Context API directly, but it usually involves a bit of boilerplate to set up. I've simplified the whole process with a straightforward API for creating providers, and useScopeCtx makes it a breeze to grab the context value anywhere within the provider's scope.
API
ScopeProvider
This wraps your children with a context provider.
import { ScopeProvider } from '~/lib/scope-provider';
function App() {
const [state, setState] = useState<MyType>(initialValue);
return (
<ScopeProvider value={{ state, setState }}>
<Dashboard />
</ScopeProvider>
);
}Props
| Prop | Type | Description |
|---|---|---|
value | unknown | The value to provide to consumers. |
children | React.ReactNode | The component subtree. |
useScopeCtx
This is how you consume the value from the nearest ScopeProvider.
import { useScopeCtx } from '~/lib/scope-provider';
function Dashboard() {
const { state } = useScopeCtx<MyType>();
return <p>Welcome, {state.someProp}..!</p>;
}Options
| Option | Type | Default | Description |
|---|---|---|---|
shouldThrow | boolean | true | Whether to throw an error if no provider is found. Returns null if used outside a provider and shouldThrow is false. |
Usage Examples
Optional Context
If you want the provider to be optional, just set shouldThrow: false:
function OptionalConsumer() {
const ctx = useScopeCtx<{ theme: string }>({ shouldThrow: false });
const theme = ctx?.theme ?? 'light';
return <div>Theme: {theme}</div>;
}