
Product
Socket Now Supports pylock.toml Files
Socket now supports pylock.toml, enabling secure, reproducible Python builds with advanced scanning and full alignment with PEP 751's new standard.
react-super-context
Advanced tools
A tiny wrapper library around the [React Context API](https://reactjs.org/docs/context.html) that removes a lot of boilerplate required to create and consume contexts.
A tiny wrapper library around the React Context API that removes a lot of boilerplate required to create and consume contexts.
npm i react-super-context
// when using TypeScript, you must define an interface for the context's value to get proper type hints
interface CounterContextModel {
count: number;
increment: () => void;
decrement: () => void;
}
// createContext expects a default value that is used if there are no providers for the context
const CounterContext = createContext<CounterContextModel>({
count: 0,
increment: () => {},
decrement: () => {},
});
// we export a provider component that is responsible for the context's states
export const CounterContextProvider = ({ children }: PropsWithChildren<{}>) => {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(Math.max(0, count - 1));
return (
<CounterContext.Provider value={{ count, increment, decrement }}>
{children}
</CounterContext.Provider>
);
};
// we also export a hook that can be used to consume the context in our components
export const useCounter = () => useContext(CounterContext);
// createSuperContext returns a custom provider and a hook for consumption
const [CounterContext, useCounter] = createSuperContext(() => {
// the state logic is the same as before
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(Math.max(0, count - 1));
// we now simply have to return the context's value
// when using TypeScript, the types are inferred and the useCounter hook will have proper type hints
return { count, increment, decrement };
});
export { CounterContext, useCounter };
const App = () => {
return (
<CounterContextProvider>
<MySecondContextProvider>
<MyThirdContextProvider>
<div>Your app with consumers comes here</div>
</MyThirdContextProvider>
</MySecondContextProvider>
</CounterContextProvider>
);
};
const App = () => (
<SuperContext contexts={[CounterContext, MySecondContext, MyThirdContext]}>
<div>Your app with consumers comes here</div>
</SuperContext>
);
1. Use the createSuperContext
function to create your context. It takes a factory function that returns the context's value and returns a context object as well as a hook to consume the state.
// CounterContext.ts
const [CounterContext, useCounter] = createSuperContext(() => {
const [count, setCount] = useState(0);
return {count, setCount};
});
export { CounterContext, useCounter };
2. To create a provider for the context, add the SuperContext
component in your app and pass it the CounterContext
created by the createSuperContext
call.
// App.tsx
const App = () => (
<SuperContext contexts={[CounterContext]}>
<CountDisplay/>
<CounterButton/>
</SuperContext>
);
3. Consume the context in your components using the useCounter
hook.
// CountDisplay.tsx
const CountDisplay = () => {
const { count } = useCounter();
return <div>{count}</div>;
};
// CounterButton.tsx
const CounterButton = () => {
const { count, setCount } = useCounter();
return <button onClick={() => setCount(count + 1)}>+1</button>;
};
1. Create a second context that uses useCounter
.
// EvenOrOddContext.ts
const [EvenOrOddContext, useEvenOrOdd] = createSuperContext(() => {
const { count } = useCounter();
return count % 2 === 0 ? "even" : "odd";
});
export { EvenOrOddContext, useEvenOrOdd };
2. Remember to add it to the contexts lists. The order of the contexts matters.
// App.tsx
const App = () => (
<SuperContext contexts={[CounterContext, EvenOrOddContext]}>
<CountDisplay/>
<CounterButton/>
</SuperContext>
);
EvenOrOddContext
depends on CounterContext
so if they were given the other way around (contexts={[EvenOrOddContext, CounterContext]}
), then the useCounter
call in EvenOrOddContext.ts
will throw an error.
3. Consume the new context.
// CountDisplay.tsx
export const CountDisplay = () => {
const { count } = useCounter();
const evenOrOdd = useEvenOrOdd();
return <div>{count} ({evenOrOdd})</div>;
};
const [Logging] = createSuperContext(() => {
const { count } = useCounter();
const evenOrOdd = useEvenOrOdd();
useEffect(() => {
console.log(`The current count is ${count} which is ${evenOrOdd}`);
}, [count, evenOrOdd]);
});
export default Logging;
Remember to always add your context objects to the SuperContext
component.
1. Create a super context with the desired props.
// CounterContext.ts
interface CounterContextProps {
initial: number;
}
const [CounterContext, useCounter] = createSuperContext(({ initial }: CounterContextProps) => {
const [count, setCount] = useState(initial);
return { count, setCount };
});
export { CounterContext, useCounter };
2. CounterContext
is a function that you can pass the props to.
// App.tsx
const App = () => (
<SuperContext contexts={[CounterContext({ initial: 10 })]}>
<CountDisplay/>
<CounterButton/>
</SuperContext>
);
In all the examples above, TypeScript is able to infer the types of both the context's value (the value returned by the factory function and by the generated hook) and the contexts' props.
const CountDisplay = () => {
const { count } = useCounter(); // inferred type: { count: number, increment: () => void, decrement: () => void }
const evenOrOdd = useEvenOrOdd(); // inferred type: "even" | "odd"
return <div>{count} ({evenOrOdd})</div>;
};
However, you can also define types explicitly:
1. Type given explicitly in createSuperContext
call.
// CounterContext.ts
interface CounterContextModel {
count: number;
increment: () => void;
decrement: () => void;
}
const [CounterContext, useCounter] = createSuperContext<CounterContextModel>(() => {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(Math.max(0, count - 1));
return { count, increment, decrement };
});
2. Type inferred when consuming the context.
const CountDisplay = () => {
const { count } = useCounter(); // inferred type: CounterContext
return <div>{count}</div>;
};
The simplest approach is to define the prop type in the argument for the factory function.
interface CounterContextProps {
initial: number;
}
const [CounterContext, useCounter] = createSuperContext(({ initial }: CounterContextProps) => {
const [count, setCount] = useState(initial);
return { count, setCount };
});
If you have defined the context's value type explicitly, you must pass the prop type as the second generic argument (at least until TypeScript gets support for partial type argument inference).
const [CounterContext, useCounter] = createSuperContext<CounterContext, CounterContextProps>(({initial}) => {
const [count, setCount] = useState(initial);
return { count, setCount };
});
The createSuperContext
function takes an optional object as the second argument, allowing you to specify a number of options.
const [CounterContext, useCounter] = createSuperContext(
() => {
const [count, setCount] = useState(0);
return { count, setCount };
},
{
displayName: "MyCounterContext",
testValue: { count: 0, setCount: () => {} },
}
);
displayName
will be the name of the context provider component in error messages. The testValue
is the value returned by the useCounter
hook in a test environment. The library will by default check if NODE_ENV === "test"
to determine if it is in a test environment, but this can be overridden with the testEnvironment
option.
If you use many of the same options on all context provided by a SuperContext
, you can use the defaultOptions
prop to set defaults:
const App = () => (
<SuperContext
contexts={[CounterContext, EvenOrOddContext]}
defaultOptions={{displayName: "MyContext"}}
>...</SuperContext>
);
In the example above, both the CounterContext
and the EvenOrOddContext
provider components will be displayed as "MyContext" in error messages.
FAQs
A tiny wrapper library around the [React Context API](https://reactjs.org/docs/context.html) that removes a lot of boilerplate required to create and consume contexts.
The npm package react-super-context receives a total of 27 weekly downloads. As such, react-super-context popularity was classified as not popular.
We found that react-super-context demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports pylock.toml, enabling secure, reproducible Python builds with advanced scanning and full alignment with PEP 751's new standard.
Security News
Research
Socket uncovered two npm packages that register hidden HTTP endpoints to delete all files on command.
Research
Security News
Malicious Ruby gems typosquat Fastlane plugins to steal Telegram bot tokens, messages, and files, exploiting demand after Vietnam’s Telegram ban.