@fullstackhouse/react-compose
v0.1.0
Published
Compose React providers and components to avoid deeply nested JSX trees
Maintainers
Readme
@fullstackhouse/react-compose
Compose React providers and components to avoid deeply nested JSX trees.
The Problem
// Provider hell - deeply nested JSX
function App() {
return (
<ThemeProvider>
<AuthProvider>
<I18nProvider>
<RouterProvider>
<QueryProvider>
<AppContent />
</QueryProvider>
</RouterProvider>
</I18nProvider>
</AuthProvider>
</ThemeProvider>
);
}The Solution
import { compose } from "@fullstackhouse/react-compose";
const App = compose([
ThemeProvider,
AuthProvider,
I18nProvider,
RouterProvider,
QueryProvider,
AppContent,
]);Installation
npm install @fullstackhouse/react-composeUsage
Basic Composition
import { compose } from "@fullstackhouse/react-compose";
const MyScreen = compose([
AuthProvider,
ThemeProvider,
MyScreenContent,
]);
// Use it like a normal component
<MyScreen />;Passing Props to Providers
Use tuple syntax [Component, props] to pass props to specific providers:
const MyScreen = compose([
[ThemeProvider, { theme: "dark" }],
[I18nProvider, { locale: "en" }],
MyScreenContent,
]);Props Flow to Content Component
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" />;Mixing Tuple and Non-Tuple Providers
const MyScreen = compose([
AuthProvider, // No props needed
[ThemeProvider, { theme: "dark" }], // With props
[QueryProvider, { staleTime: 5000 }], // With props
DataProvider, // No props needed
MyScreenContent,
]);API
compose(providers)
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)
Provider<TProps>
Type for a provider in the composition array:
type Provider<TProps> =
| ComponentType<PropsWithChildren<TProps>>
| readonly [ComponentType<PropsWithChildren<TProps>>, TProps];How It Works
Components are nested in order, with the first being the outermost wrapper:
compose([A, B, C])
// Renders as:
<A>
<B>
<C />
</B>
</A>License
MIT
