Compose React providers and components to avoid deeply nested JSX trees.
// Provider hell - deeply nested JSX
function App() {
return (
<ThemeProvider>
<AuthProvider>
<I18nProvider>
<RouterProvider>
<QueryProvider>
<AppContent />
</QueryProvider>
</RouterProvider>
</I18nProvider>
</AuthProvider>
</ThemeProvider>
);
}import { compose } from "@fullstackhouse/react-compose";
const App = compose([
ThemeProvider,
AuthProvider,
I18nProvider,
RouterProvider,
QueryProvider,
AppContent,
]);npm install @fullstackhouse/react-composeimport { compose } from "@fullstackhouse/react-compose";
const MyScreen = compose([
AuthProvider,
ThemeProvider,
MyScreenContent,
]);
// Use it like a normal component
<MyScreen />;Use tuple syntax [Component, props] to pass props to specific providers:
const MyScreen = compose([
[ThemeProvider, { theme: "dark" }],
[I18nProvider, { locale: "en" }],
MyScreenContent,
]);Props passed to the composed component are forwarded to the innermost component:
interface ContentProps {
userId: string;
}
function UserProfile({ userId }: ContentProps) {
return <div>User: {userId}</div>;
}
const Screen = compose<ContentProps>([
AuthProvider,
UserProfile,
]);
// Props are passed to UserProfile
<Screen userId="123" />;const MyScreen = compose([
AuthProvider, // No props needed
[ThemeProvider, { theme: "dark" }], // With props
[QueryProvider, { staleTime: 5000 }], // With props
DataProvider, // No props needed
MyScreenContent,
]);Composes an array of React components/providers into a single component.
Parameters:
providers- Array of components or[component, props]tuples
Returns:
- A React component that renders all providers nested in order
Type Parameters:
TProps- Props type for the composed component (optional, defaults toobject)
Type for a provider in the composition array:
type Provider<TProps> =
| ComponentType<PropsWithChildren<TProps>>
| readonly [ComponentType<PropsWithChildren<TProps>>, TProps];Components are nested in order, with the first being the outermost wrapper:
compose([A, B, C])
// Renders as:
<A>
<B>
<C />
</B>
</A>MIT