From harness-claude
Applies React container/presentational pattern to split data-fetching containers from stateless UI components, enabling reuse, easier testing, and mocking.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Separate data-fetching containers from stateless presentational components
Declaratively handles async loading states using React Suspense boundaries for lazy-loading components and data fetching with libraries like React Query or SWR in React 18+ apps.
Guides implementation of modern React patterns: hooks, component composition, state management, performance optimizations, concurrent features. Use for building or refactoring components.
Provides quick reference for React 18+ patterns including functional components, container/presentational composition, and compound components during frontend development.
Share bugs, ideas, or general feedback.
Separate data-fetching containers from stateless presentational components
<Name>Container): fetches or manages data, passes it as props to the presentational component<Name>): receives data as props, renders UI, has no data-fetching logicuseEffect, no fetch calls.// Presentational — pure, testable, no data concerns
interface DogImageProps { imageUrl: string | null; loading: boolean }
function DogImage({ imageUrl, loading }: DogImageProps) {
if (loading) return <p>Loading...</p>;
return imageUrl ? <img src={imageUrl} alt="dog" /> : null;
}
// Container — data concern only
function DogImageContainer() {
const [imageUrl, setImageUrl] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://dog.ceo/api/breeds/image/random')
.then((r) => r.json())
.then((d) => { setImageUrl(d.message); setLoading(false); });
}, []);
return <DogImage imageUrl={imageUrl} loading={loading} />;
}
This pattern predates hooks but remains valid. With hooks, the "container" logic is often extracted into a custom hook (useDogImage) instead of a wrapper component, which achieves the same separation with less nesting.
Modern equivalent: Extract data logic into a custom hook, use the hook in the component:
function DogImage() {
const { imageUrl, loading } = useDogImage(); // hook is the "container"
if (loading) return <p>Loading...</p>;
return imageUrl ? <img src={imageUrl} alt="dog" /> : null;
}
With React Server Components: The server/client split supersedes this pattern for many cases — server components handle data fetching, client components handle interactivity.
https://patterns.dev/react/presentational-container-pattern