install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/react-container-presentational" ~/.claude/skills/intense-visions-harness-engineering-react-container-presentational && rm -rf "$T"
manifest:
agents/skills/claude-code/react-container-presentational/SKILL.mdsource content
React Container/Presentational Pattern
Separate data-fetching containers from stateless presentational components
When to Use
- A component mixes data-fetching logic with rendering, making it hard to test
- You want to reuse the same UI with different data sources
- You are building a component library where UI and data concerns must be independent
- You need to mock data easily in Storybook or unit tests
Instructions
- Split the component in two:
- Container (
): fetches or manages data, passes it as props to the presentational component<Name>Container - Presentational (
): receives data as props, renders UI, has no data-fetching logic<Name>
- Container (
- The presentational component is a pure function of its props — no
, no fetch calls.useEffect - The container handles loading states, errors, and side effects.
- Test the presentational component in isolation by passing mock props.
// 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} />; }
Details
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.
Source
https://patterns.dev/react/presentational-container-pattern
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.